开发者网络

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 103|回复: 1

安卓期末大作业——仿番茄小说APP

[复制链接]

1

主题

2

帖子

3

积分

新手上路

Rank: 1

积分
3
发表于 2022-12-12 02:29:42 | 显示全部楼层 |阅读模式


上海建桥学院

信息技术学院
《移动应用开发实践》
实践报告
APP名称: 番茄免费小说
专    业:               
班    级:         
学生姓名:      
学    号:         
指导教师:               
要求:
格式:宋体,小四号字;首行缩进;行距:1.5倍。

  • 每人独立完成Android App的设计与开发
  • App必须包含SOLite数据库操作
一、所调查的App简介。(限200字以内)
番茄小说是抖音 旗下的免费网文阅读APP,致力于为读者提供畅快不花钱的极致阅读体验,于2019年11月正式上线。
番茄小说拥有海量正版小说,涵盖言情、玄幻、悬疑、都市等全部主流网文类型,以及大量热剧原著和经典出版物,支持用户看书听书。

  • 你要参照的App的界面截图及界面对应的流程图和功能图,并给出具体的文字说明。


功能图




参照的App的界面截图


三、技术剖析(调查的App界面可以运用哪些课程所学内容实现,请对照一一说明)
3.1 首页
首页从上往下整体可以用垂直的线性布局实现,顶部的搜索框可以用RelativeLayout相对布局实现,接下来的4x4的排行榜可以HorizontalScrollView和RecyclerView瀑布流实现。
底部导航栏可以用成熟的BottomNavigationView技术方案实现,底部导航图片可以采用ventor矢量图标。
3.2 榜单
可以用左右组合RecyclerView列表实现,根据左侧分类动态显示右侧的书籍。
3.3 书架
可以采用3列布局的列表实现,单击事件可以查看书籍详情,长按事件可以删除书籍
3.4 我的
可以采用ConstraintLayout布局实现。退出登录可以通过button按钮单击事件实现
四、App实现
1.界面完成的截图
[/table][table]
2.界面布局代码

  • 首页
    <?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"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".ui.home.HomeFragment"
        android:orientation="vertical">
        <RelativeLayout
            android:id="@+id/re1"
            android:layout_width="match_parent"
            android:layout_height="70dp"
            android:background="#E6E8EA">
            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="42dp"
                android:layout_centerInParent="true"
                android:layout_marginLeft="50dp"
                android:background="@drawable/back3">
                <ImageView
                    android:layout_width="35dp"
                    android:layout_height="35dp"
                    android:layout_centerVertical="true"
                    android:layout_marginLeft="5dp"
                    android:background="@drawable/ic_baseline_search_24" />
                <EditText
                    android:id="@+id/edinput"
                    android:layout_width="match_parent"
                    android:layout_height="50dp"
                    android:layout_marginLeft="43dp"
                    android:layout_marginRight="55dp"
                    android:background="#FCFDFD"
                    android:hint="请输入搜索内容" />
                <TextView
                    android:id="@+id/tv_refresh1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentRight="true"
                    android:layout_centerVertical="true"
                    android:layout_marginRight="10dp"
                    android:text="搜索"
                    android:textColor="#A60F43"
                    android:textSize="17dp" />
            </RelativeLayout>
        </RelativeLayout>
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <TextView
                android:id="@+id/tv_rank"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="排行榜"
                android:textSize="32dp"
                android:textStyle="bold"
                />
            <TextView
                android:id="@+id/all_rank"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="完整榜单>"
                android:textSize="24dp"
                android:layout_alignParentRight="true"
                />
        </RelativeLayout>
        <HorizontalScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/homeRecyclerView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@color/colorContent"
                android:overScrollMode="never"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.0"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />
        </HorizontalScrollView>
    </LinearLayout>
  • 榜单
<?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:orientation="horizontal"
    android:weightSum="10"
    tools:context=".ui.snack.SnackFragment">
    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="2"
        android:orientation="vertical">
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/snackLeftRecyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#4DEEEEEE"
            android:overScrollMode="never" />
    </LinearLayout>
    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="8"
        android:orientation="vertical"
        android:overScrollMode="never">
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/snackRightRecyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/colorBgWhite"
            android:overScrollMode="never" />
    </LinearLayout>
</LinearLayout>

  • 书架
    <?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:orientation="vertical"
        tools:context=".ui.place.PlaceFragment">
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/placeRecyclerView"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:background="@color/colorContent"
            android:overScrollMode="never" />
    </LinearLayout>
  • 我的
<?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="@color/colorContent"
    tools:context=".ui.my.MyFragment">
    <ScrollView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:overScrollMode="never"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">
        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <androidx.constraintlayout.widget.ConstraintLayout
                android:id="@+id/constraintLayout"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:background="@drawable/detail_info"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                tools:ignore="MissingConstraints">
                <de.hdodenhof.circleimageview.CircleImageView
                    android:id="@+id/myUserHead"
                    android:layout_width="80dp"
                    android:layout_height="80dp"
                    android:layout_marginStart="16dp"
                    android:layout_marginTop="24dp"
                    android:layout_marginBottom="24dp"
                    android:src="@mipmap/hejubian"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />
                <TextView
                    android:id="@+id/myUserNickName"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="17dp"
                    android:layout_marginTop="24dp"
                    android:text="未登录"
                    android:textSize="22sp"
                    app:layout_constraintStart_toEndOf="@+id/myUserHead"
                    app:layout_constraintTop_toTopOf="parent" />
                <TextView
                    android:id="@+id/myUserName"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="17dp"
                    android:layout_marginTop="8dp"
                    android:text=""
                    android:textSize="18sp"
                    app:layout_constraintStart_toEndOf="@+id/myUserHead"
                    app:layout_constraintTop_toBottomOf="@+id/myUserNickName" />
            </androidx.constraintlayout.widget.ConstraintLayout>
            <LinearLayout
                android:id="@+id/linearLayout"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginTop="16dp"
                android:background="@drawable/radius_content"
                android:orientation="horizontal"
                android:padding="10sp"
                android:weightSum="4"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/constraintLayout">
                <LinearLayout
                    android:id="@+id/myOrderView"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:orientation="vertical">
                    <ImageView
                        android:layout_width="match_parent"
                        android:layout_height="55dp"
                        android:padding="8dp"
                        android:src="@drawable/ic_baseline_assignment_24dp" />
                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:gravity="center_horizontal"
                        android:text="我的订单" />
                </LinearLayout>
                <LinearLayout
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:orientation="vertical">
                    <ImageView
                        android:layout_width="match_parent"
                        android:layout_height="55dp"
                        android:padding="8dp"
                        android:src="@drawable/ic_sharp_monetization_on_24dp" />
                    <TextView
                        android:id="@+id/textView4"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:gravity="center_horizontal"
                        android:text="待付款" />
                </LinearLayout>
                <LinearLayout
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:orientation="vertical">
                    <ImageView
                        android:layout_width="match_parent"
                        android:layout_height="55dp"
                        android:padding="8dp"
                        android:src="@drawable/ic_baseline_question_answer_24dp" />
                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:gravity="center_horizontal"
                        android:text="待评价" />
                </LinearLayout>
                <LinearLayout
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:orientation="vertical">
                    <ImageView
                        android:layout_width="match_parent"
                        android:layout_height="55dp"
                        android:padding="8dp"
                        android:src="@drawable/ic_baseline_report_24dp" />
                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:gravity="center_horizontal"
                        android:text="退款" />
                </LinearLayout>
            </LinearLayout>
            <LinearLayout
                android:id="@+id/linearLayout2"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="1dp"
                android:layout_marginTop="16dp"
                android:background="@drawable/radius_content"
                android:orientation="vertical"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/linearLayout">
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="45dp"
                    android:gravity="center_vertical"
                    android:paddingStart="16dp"
                    android:text="支付设置"
                    android:textSize="18sp"
                    tools:ignore="RtlSymmetry" />
                <View
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:background="#EEEEEE" />
                <TextView
                    android:id="@+id/myModifyText"
                    android:layout_width="match_parent"
                    android:layout_height="45dp"
                    android:gravity="center_vertical"
                    android:paddingStart="16dp"
                    android:text="修改地址"
                    android:textSize="18sp"
                    tools:ignore="RtlSymmetry" />
                <LinearLayout
                    android:id="@+id/myModifyView"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="#1A409EFF"
                    android:orientation="vertical"
                    android:visibility="gone">
                    <EditText
                        android:id="@+id/editTextTextPersonName2"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginLeft="32sp"
                        android:layout_marginTop="22sp"
                        android:layout_marginRight="32sp"
                        android:layout_marginBottom="12sp"
                        android:ems="10"
                        android:hint="请输入新的手机号码"
                        android:inputType="textPersonName" />
                    <EditText
                        android:id="@+id/editTextTextPersonName3"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginLeft="32sp"
                        android:layout_marginTop="12sp"
                        android:layout_marginRight="32sp"
                        android:layout_marginBottom="12sp"
                        android:ems="10"
                        android:hint="请输入新的收货地址"
                        android:inputType="textPersonName" />
                    <Button
                        android:id="@+id/myModifyBtn"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="end"
                        android:layout_marginEnd="32sp"
                        android:layout_marginBottom="12sp"
                        android:text="确定" />
                </LinearLayout>
                <View
                    android:layout_width="match_parent"
                    android:layout_height="1dp"
                    android:background="#EEEEEE" />
            </LinearLayout>
            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginTop="16dp"
                android:layout_marginBottom="16dp"
                android:background="@drawable/radius_content"
                android:orientation="vertical"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/linearLayout2">
                <TextView
                    android:id="@+id/logoutBtn"
                    android:layout_width="match_parent"
                    android:layout_height="45dp"
                    android:gravity="center"
                    android:paddingStart="16dp"
                    android:text="退出账号"
                    android:textSize="16sp"
                    tools:ignore="RtlSymmetry" />
            </LinearLayout>
        </androidx.constraintlayout.widget.ConstraintLayout>
    </ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
3.App功能实现关键代码
(1)首页
private void initHomeAdapter() {
        // 实例化电子书列表适配器对象
        HomeAdapter adapter = new HomeAdapter(DataServer.getHomeList());
        // 设置动画效果
        adapter.setAnimationEnable(true);
//        adapter.setAnimationFirstOnly(false);
//        adapter.setAnimationWithDefault(BaseQuickAdapter.AnimationType.SlideInBottom);
        adapter.setAdapterAnimation(new MyAnimation3());
        // 设置头部
        adapter.setHeaderView(getHeadView(), 1);
        // 设置尾部
        adapter.setFooterView(getFooterView(), 1);
        // 点击事件监听器
        adapter.setOnItemClickListener((adapter1, view, position) -> {
            Snack snack = (Snack) adapter1.getItem(position);
            DetailActivity.actionStart(getContext(), snack);
        });
        // 设置适配器
        homeRecyclerView.setAdapter(adapter);
}

  • 榜单
/**
     * 初始化左边适配器
     */
    @SuppressLint("ResourceAsColor")
    private void initLeftAdapter() {
        // 实例化左边适配器对象
        SnackLeftAdapter leftAdapter = new SnackLeftAdapter(DataServer.getSnackOrderList());
        // 设置动画效果
        leftAdapter.setAnimationEnable(true);
        leftAdapter.setAnimationFirstOnly(false);
        leftAdapter.setAnimationWithDefault(BaseQuickAdapter.AnimationType.SlideInLeft);
        // 触发点击按钮
        leftAdapter.setOnItemClickListener((adapter, view, position) -> {
            if (position != leftSelectPosition) {
                String item = (String) adapter.getItem(position);
                // 原本选中的item变成未选中颜色
                Objects.requireNonNull(adapter.getViewByPosition(leftSelectPosition, R.id.snackLeftType)).setBackgroundResource(R.color.colorContent);
                // 当前item变成选中颜色
                Objects.requireNonNull(adapter.getViewByPosition(position, R.id.snackLeftType)).setBackgroundResource(R.color.colorBgWhite);
                leftSelectPosition = position;
                // 刷新右边列表
//                    rightAdapter.setAnimationWithDefault(BaseQuickAdapter.AnimationType.SlideInBottom);
                rightAdapter.setAnimationEnable(false);
                switch (position) {
                    case 1:
                        rightAdapter.setNewInstance(DataServer.getGuangxiList());
                        break;
                    case 2:
                        rightAdapter.setNewInstance(DataServer.getGuangzhouList());
                        break;
                    case 3:
//                        rightAdapter.setNewInstance(DataServer.getBeijingList());
                        break;
                    case  4:
//                        rightAdapter.setNewInstance(DataServer.getChongqingList());
                        break;
                    default:
                        rightAdapter.setNewInstance(DataServer.getFujianList());
                        break;
                }
            }
        });
        // 设置左边列表适配器
        leftRecyclerview.setAdapter(leftAdapter);
    }
    /**
     * 初始化右边适配器
     */
    public void initRightAdapter() {
        // 实例化右边适配器对象
        rightAdapter = new SnackRightAdapter(DataServer.getFujianList());
        // 设置动画效果
        rightAdapter.setAnimationEnable(true);
//        rightAdapter.setAnimationFirstOnly(false);
        rightAdapter.setAnimationWithDefault(BaseQuickAdapter.AnimationType.SlideInRight);
        // 设置尾部
        rightAdapter.addFooterView(getFooterView());
        // 点击item事件
        rightAdapter.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {
                Snack snack = (Snack) adapter.getItem(position);
                DetailActivity.actionStart(getContext(), snack);
            }
        });
        // 左边列表加入书架点击事件
        rightAdapter.addChildClickViewIds(R.id.snackRightAddBtn);
        rightAdapter.setOnItemChildClickListener((adapter, view, position) -> {
            Snack snack = (Snack) adapter.getItem(position);
            if (view.getId() == R.id.snackRightAddBtn) {
                if (!MyApplication.getCartSnacks().contains(snack)) {
                    // 添加到书架
                    snack.setCount(1);
                    MyApplication.getCartSnacks().add(snack);
                    Tips.show("已添加" + snack.getName() + "到书架");
                } else {
                    Tips.show("已在书架中,不能重复添加");
                }
            }
        });
        // 设置右边列表适配器
        rightRecyclerView.setAdapter(rightAdapter);
    }

  • SQLite数据库表设计(格式如下,一个数据表对应一个表格)
字段含义类型
name书籍名称string
price书籍热度double
Image书籍图片Int
detail书籍详情string
列名数据类型长度允许空说明
usernamevarchar20N用户名
passwordvarchar30Y密码
addressvarchar100N收货地址
idint10N编号
headimageint100Y头像
5.调查的App界面中你觉得哪些设计不合理,你是如何改进的(选做)
首页列表在不同设备显示的比例不同,可能导致美观度不够,可以进一步根据不同设备进行适配

  • 测试用例
  • 搜索
输入:“黑科技1”
搜索结果:


(2)加入书架
输入:点击加入书架
结果文字:提示成功加入书架

  • 总结(不少于500字,本次调查目的、过程、开发经历等)
1)通过半个学期的学习,基本掌握了Android应用程序开发的一般流程。对常用控件基本掌握其用法,对其事件的监听方法也基本掌握。学习Android不仅是对前沿开发技术的了解,也是对编程知识的一次提升。
2)通过学习Android的控件、布局、Activity、Service等一系列基础知识,对整个Android的开发有了大致的了解。例如:要的布局(或者控件),在学习界面中,我发现Android为我们提供了很好的类似反射机制,通过Layout文件夹下的配置文件,可以快速的形成界面,在配置文件可以设置属性或者样式都是很快捷方便对比较特殊的界面也可以通过处理嵌入到指定的界面,同样你可以通过java代码直接创建View进行添加,不过这种方式比较复杂。
3)对一些点击、选中、按键等处理的事件,界面之间的跳转Intent管理,通过Bundle对数据在界面之间进行传输。
android是一种很错的手机系统,使用起来简单,而且可以根据自己的需求选择适合自己的版本,非常的方便。我要多多学习关于android的知识,在未来,将android系统研发的更加人性化,使用起来更加的舒适。
回复

使用道具 举报

0

主题

5

帖子

8

积分

新手上路

Rank: 1

积分
8
发表于 2025-3-23 09:16:57 | 显示全部楼层
为了三千积分!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|开发者网络

GMT+8, 2025-4-7 11:26 , Processed in 0.092849 second(s), 22 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表