一、概述11
1.1 课题描述11
1.2 需求剖析22
1.3 开拓环境33
二、剖析与概要设计55
2.1 系统功能剖析55
2.2 系统模块构造图66
2.3 数据库表的设计66
三、旅游系统的登录功能模块的详细设计88
3.1 登录模块的功能描述88
3.2 登录模块的界面布局的设计99
3.3 注册模块的Activity的设计1111
3.3.1 添加用户模块信息1414
3.3.2 删除用户模块信息1616
四、北京旅游系统的旅游攻略功能模块的详细设计2121
4.1 旅游攻略模块的功能描述2121
4.2 旅游攻略模块的界面布局的设计2222
4.3 旅游攻略模块的Activity的设计2424
4.3.1旅游攻略的列表的实现2626
4.3.2旅游攻略的菜单的实现2929
4.3.3 查找旅游攻略模块信息3131
五、系统测试3636
5.1 登录功能模块测试3636
5.2 景点攻略功能模块测试3636
5.3 社区评论功能模块测试3737
六、项目总结3838
七、参考文献3939
一、概述1.1 课题描述中国旅游业发展趋势众所周知已经越来越火爆,而北京的旅游景点更是许多人的第一选择,但是只从线下购票的办法很难实现持续发展。随着生活水平的不断提高,旅游成为人们生活不可或缺的一部分;旅游本是享受,然而传统旅游的一成不变的模式、千篇一律的线路,成为游客集中抱怨的焦点;因此,自助游越来越受到人们的青睐。
现在旅游行业不同昔日,逐年的高速发展人们已经离不开网络了。以前旅游的方法和现在旅游已经有很大的不同,互联网可以让人们更好的生活,在想要旅游点击网络就可以得到大量的旅游攻略、景点先容、小理票务、预订酒店等信息,利用网络的方便来旅行已经是大势所趋,利用互联网对付旅游爱好者来说方使了很多,也节省了很多的韶光来做一些排队买票这类的事,有关旅游这方面的做事都得到了经济上的增长,现在旅游的趋势是旅游的紧张竞争手段转移到了于机运用上,利用手机的便捷及手机运用的全面性取得了广大旅游用户的喜好。
现在有关旅游的运用软件主攻的做事方向不同,个中一类是原谅性的,也便是在一个运用上可以选择多个运用,其余一类具有专攻性子,如酒店预订功能,票务预订功能、旅游攻略功能等,不论它们方向哪一种,每一位旅行爱好者的手机中都会有一款旅游运用。现在是物联网大数据时期,各种各样的信息将向每一个人袭来,手机中的旅游运用也会供应游客各种有关旅游的信息。
大部分利用者都希望有一种全面的旅游手机运用软件,以是制作手机旅游软件须要有更多的实用功能,任何一个利用者都可以在软件中找到自己想要的做事,这就匆匆成了一体化做事的产生,这些用户想要功能在一起,就可以让用户更加快捷的去旅游,利用一些零散的韶光,完备足够旅行者理解想要去的地方。这些年来手机上的旅游运用越来越多,让人们不再以以前单一的旅游办法活动,旅游是放松人精神的一种活动,可以让人们更加热爱生活享受生活,旅游运用逐年的改进,方便了广大的旅行爱好者,只假如用户有可能须要的做事,手机旅游运用中都会有,这就让游客感想熏染到旅游是一种纯粹的亨受生活的办法,现在人们利用的手机运用有很多。
在科技飞速发展的本日,我们已经离不开网络,手机旅游运用中的各种功能不断改进,越来越强大,各种旅游软件公司都想让自己在旅游业有更强的竞争力,让更多的用户利用它们的产品。网络与手机的结合使旅行更加方便,因此旅游运用软件也越来越火爆,成为了人们必备的手机运用。随着自助游的快速发展,市场上关于旅游的运用程序朝阳东升,但针对旅游景点开拓的运用程序尚处于不成熟阶段,以是这次我开拓一个关于北京旅游的APP。
1.2 需求剖析1.2.1 技能需求北京旅游App方便广大游客更随意马虎针对性的对地方进行旅游攻略,北京旅游APP系统在Java、Android、XML、SQLite数据库上的技能运用需求极其广泛,包含界面和后端程序的开拓。通过借助这些技能使全体前后真个衔接变得更加顺利,并且在开拓程序时所利用的系统环境、运用环境上都有较为明显的适用表示,能够做到功能完善、整体架构清晰、整洁划一的操作流程。在对付数据库的建立和掩护方面,都更贴合系统哀求,实现数据精确安全,担保系统的顺利进行。同时,旅游APP对付全体类似系统的技能设计进行了详细的剖析,这对付开拓本系统所利用的技能环境供应了极大的帮助。
1.2.2 功能需求(1)登录
首先进行登录操作,通过输入精确的用户名、密码即可登录成功,还有记住密码和自动登录功能,然后进入旅游首页界面,从而对数据进行干系操作,达到可视化的实时效果。
注册在注书页面,可以进行游客信息的注册,能够选择账号和填写密码并添加到数据库中。首页首页头部有搜索,可以搜索旅游信息功能,往下便是一个轮播图,是北京旅游景点的特色地方,其次是各个景点的点击,能进行查看景点。创造采取瀑布式布局,创造页面可以实现旅游信息的查看,可查看景点的详细信息,点击图片进行详细历史文化的展示,包含RecyclerView展示各种景点,点击图片可以跳转到相应的景点先容。社区评论展示各个景点评论的界面。个人中央游客信息展示,包含4个按钮,包含个人信息、账号安全、我的收藏、旅行日记4个按钮,可以进行自己的旅游心得记录。1.3 开拓环境1.3.1 Android简介
Android是一种基于Linux的自由及开放源代码的操作系统,Android 分为四个层,从高层到低层分别是运用程序层、运用程序框架层、系统运行库层和 Linux内核层。Android有四大基本组件:Activity、Service、broadcast receiver、Content Provider。个中Activity是四大组件中最基本的一个,但根本并不等同于大略、不主要。正好相反,Activity作为根本组件,学好Activity便是我们开拓者学好Android的条件。1.3.2 Java简介Java措辞是一款非常热门的并且又具有代表性的编程措辞,在实际运用过程中有着不可替代的浸染。Java措辞实际上是一种面向工具类型的编程措辞,在实际开拓领域中也会借助系统自带的功能去实现系统的设计,包含类、接口等功能的赞助实现,以此完玉成部系统的设计。那么对付个中的接口来说,封装可以说是一种很好的赞助办法,可以按照人们传统的思想不雅观念,实现父与子之间的功能的继续,免去编写代码时的重复度,简化繁芜性,实现动态、多态的运用环境,达到标准的运用效果。Java措辞实际上便是全体系统的后台,紧张实现程序的后台管理,通过结合类、接口并配置数据库连接等操作来完玉成部后端数据的动态显示,实现对存储数据的高效衔接和日常交互、掩护的一体化管理。1.3.3 XML简介XML的大略易于在任何运用程序中读/写数据,这使XML很快成为数据交流措辞,虽然不同的运用软件也支持其他的数据交流格式,但不久之后它们都将支持XML,那就意味着程序可以更随意马虎的与Windows、Mac OS、Linux以及其他平台下产生的信息结合,然后可以很随意马虎加载XML数据到程序中并剖析它,并以XML格式输出结果。扩展标记措辞与Access,Oracle和SQL Server等数据库不同,数据库供应了更强有力的数据存储和剖析能力,例如:数据索引、排序、查找、干系同等性等,可扩展标记措辞仅仅是存储数据。事实上它与其他数据表现形式最大的不同是:可扩展标记措辞极其大略,这是一个看上去有点琐细的优点,但正是这点使它分歧凡响。1.3.4 SQLite数据库简介SQLite是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它的设计目标是嵌入式的,而且已经在很多嵌入式产品中利用了它,它占用资源非常的低,在嵌入式设备中,可能只须要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序措辞相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源的天下著名数据库管理系统来讲,它的处理速率比他们都快。1.3.5运行环境需求操作系统: Android手机基于Linux 操作系统Android系统哀求无相应韶光为5秒,以是旅游攻略、景点查看、社区评论、个人中央、揭橥意见等等操作的系统相应韶光最长均不能超过5秒。支持环境:Android 11-13版本。二、系统剖析与概要设计2.1 系统功能剖析1.第一个页面是用户登录界面,有用户注册、用户登录、退出、记住我的下次再说功能。退出Dialog与用户交互。有记录登录功能(Sharedpreferences实现):设计注册和上岸界面,哀求实现保存用户登录信息的功能,用户第一次登录时可设置是否记录密码和是否自动登录。如果用户勾选记住密码复选框,则下次登录时,会直接默认登录系统。用户如果想切换账号,可以先退出账号再登录。2. 注册界面,若用户合法完成注册后返回到登录页面,并利用Toast提示注册成功,密码和账号都不能为空,否则会利用Toast提示账号不能为空,密码不能为空 。3. 登录成功后,默认显示的页面是首页,下方导航栏的是旅游攻略、社区评论和个人中央。4. 首页Fragment,上面有一个搜索框,搜索框下面紧挨着是每一个景点的先容图,可以点击到关于北京海洋馆、南宫旅游景区、长城等的页面进行景点展示先容。创造Fragment,包含RecyclerView展示各种景点,点击图片可以跳转到相应的景点先容。6. 社区评论Fragment,展示各个景点评论的界面。
7.个人中央Fragment,包含个人信息、账号安全、我的收藏、旅行日记4个按钮,可以进行自己的旅游心得记录。2.2 系统模块构造图
图2-12.3 数据库表的设计用户管理模块用户管理tb_user用来存储用户个人信息,紧张包括username、passwordphone等字段。
tb_user表构造如表2-2所示:
表2-2 tb_user表
名称 类型 是否可空 备注username text 是 登录名password text 是 密码景点信息管理模块旅游信息表tb_goods用来存储景点信息,紧张包括id、imgId、goodsName、goodsStock等字段。
t_goods表构造如表2-3所示:
表2-3 t_goods表
名称 类型 是否可空 备注id integer 否 主键自动递增imgId integer 是 图片idgoodsName text 是 景点名客户端、做事器和数据库之间的访问过程图:
图2-2
3.1 登录模块的功能描述登录模块的功能是游客在文本框中输入用户名和密码后,点击“登录”按钮,activity会获取到输入的用户名和密码,并且利用数据库进行条件查询,将查询到的数据放入cursor游标工具中,然后进行判断,若cursor能够进行游标下移操作,则证明用户名和密码精确,然后将从数据库中取出的id等字段数据添加到bundle中用,再将bundle通过intent.putExtras(bundle)方法存入intent以进行activity之间的数据传输,末了通过startActivity跳转到MActivity,登录成功。若输入的用户名和密码禁绝确或有未填写项,则利用Toast提示用户名或密码禁绝确。
3.2 登录模块的界面布局的设计
图3-1
public class LoginActivity extends Activity {
MySqliteOpenHelper helper = null;
private static final String TAG = “LoginActivity”;
private Activity activity;
private ActionBar mTitleBar;//标题栏
private EditText etAccount;//手机号
private EditText etPassword;//密码
private TextView tvRegister;//注册
private Button btnLogin;//登录按钮
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activity=this;
helper = new MySqliteOpenHelper(this);
setContentView(R.layout.activity_login);//加载页面
etAccount =(EditText) findViewById(R.id.et_account);//获取手机号
etPassword=(EditText)findViewById(R.id.et_password);//获取密码
tvRegister=(TextView)findViewById(R.id.tv_register);//获取注册
btnLogin=(Button)findViewById(R.id.btn_login);//获取登录
mTitleBar = (ActionBar)findViewById(R.id.myActionBar);
mTitleBar.setData(activity,”登录”,0, 0, 0,getResources().getColor(R.color.colorPrimary), new ActionBar.ActionBarClickListener() {
@Override
public void onLeftClick() {
finish();
}
@Override
public void onRightClick() {
}
});
登录页面利用了线性布局,利用一个ImageView图片控件、两个EditText和两个Button实现了用户名和密码的输入框以及登录和注册两个按钮。
3.3 注册模块的Activity的设计
图3-2用户注书页面采取相对布局,注书页面构造上利用线性布局的排列,该页面含有多少个文本输入框和按钮,一个可点击的图片按钮和一个单选按钮组,可以知足用户填写信息的须要。
tvRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//跳转到注书页面
Intent intent=new Intent(activity, RegisterActivity.class);
startActivity(intent);
}
});
//设置点击按钮
btnLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//关闭虚拟键盘
InputMethodManager inputMethodManager= (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(v.getWindowToken(),0);
//获取要求参数
String account= etAccount.getText().toString();
String password=etPassword.getText().toString();
if (“”.equals(account)){//账号不能为空
Toast.makeText(activity,”账号不能为空”, Toast.LENGTH_LONG).show();
return;
}
if (“”.equals(password)){//密码为空
Toast.makeText(activity,”密码为空”, Toast.LENGTH_LONG).show();
return;
}
User mUser = null;
String sql = “select from user where account = ?”;
SQLiteDatabase db = helper.getWritableDatabase();
Cursor cursor = db.rawQuery(sql, new String[]{account});
if (cursor != null && cursor.getColumnCount() > 0) {
while (cursor.moveToNext()) {
Integer dbId = cursor.getInt(0);
String dbAccount = cursor.getString(1);
String dbPassword = cursor.getString(2);
String dbNickName = cursor.getString(3);
Integer dbAge = cursor.getInt(4);
String dbEmail = cursor.getString(5);
mUser = new User(dbId, dbAccount,dbPassword,dbNickName,dbAge,dbEmail);
}
}
db.close();
if (mUser != null) {
if (!password.equals(mUser.getPassword())) {
Toast.makeText(LoginActivity.this, “密码缺点”, Toast.LENGTH_SHORT).show();
}else{
SPUtils.put(LoginActivity.this,SPUtils.USER_ID,mUser.getId());
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
}else{
Toast.makeText(LoginActivity.this, “账号不存在”, Toast.LENGTH_SHORT).show();
}
}
});
}
@Override
protected void onResume() {
super.onResume();
}
}
图3-3
3.3.1 添加用户模块信息
private void initView() {
User user = null;
String sql = “select from user where id = ?”;
SQLiteDatabase db = helper.getWritableDatabase();
Cursor cursor = db.rawQuery(sql, new String[]{String.valueOf(userId)});
if (cursor != null && cursor.getColumnCount() > 0) {
while (cursor.moveToNext()) {
Integer dbId = cursor.getInt(0);
String dbAccount = cursor.getString(1);
String dbPassword = cursor.getString(2);
String dbNickName = cursor.getString(3);
Integer dbAge = cursor.getInt(4);
String dbEmail = cursor.getString(5);
user = new User(dbId, dbAccount,dbPassword,dbNickName,dbAge,dbEmail);
}
}
db.close();
if (user != null) {
tvAccount.setText(user.getAccount());
etNickName.setText(user.getNickName());
etAge.setText(String.valueOf(user.getAge()));
etEmail.setText(user.getEmail());
}
//保存
btnSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = helper.getWritableDatabase();
String nickName = etNickName.getText().toString();
String age = etAge.getText().toString();
String email = etEmail.getText().toString();
if (“”.equals(nickName)) {
Toast.makeText(mActivity,”昵称不能为空”, Toast.LENGTH_SHORT).show();
return;
}
if (“”.equals(age)) {
Toast.makeText(mActivity,”年事不能为空”, Toast.LENGTH_SHORT).show();
return;
}
if (“”.equals(email)) {
Toast.makeText(mActivity,”邮箱不能为空”, Toast.LENGTH_SHORT).show();
return;
}
String updateSql = “update user set nickName=?,age=?,email=? where id =?”;
db.execSQL(updateSql,new Object[]{nickName,age,email,userId});
db.close();
Toast.makeText(mActivity,”保存成功”, Toast.LENGTH_SHORT).show();
finish();//关闭页面
}
});
}
图3-4
3.3.2 删除用户模块信息
public class CollectActivity extends AppCompatActivity {
MySqliteOpenHelper helper = null;
private Activity myActivity;
private ActionBar mTitleBar;//标题栏
private LinearLayout llEmpty;
private RecyclerView rvCollectList;
private CollectAdapter mCollectAdapter;
private List<Strategy> strategyList;
private Integer userId;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_collect);
myActivity = this;
helper = new MySqliteOpenHelper(this);
rvCollectList = findViewById(R.id.rv_collect_list);
llEmpty = findViewById(R.id.ll_empty);
mTitleBar = (ActionBar) findViewById(R.id.myActionBar);
mTitleBar.setData(myActivity, “我的收藏”, R.drawable.ic_back, R.drawable.ic_clear, 0, getResources().getColor(R.color.colorPrimary), new ActionBar.ActionBarClickListener() {
@Override
public void onLeftClick() {
finish();
}
@Override
public void onRightClick() {
AlertDialog.Builder dialog = new AlertDialog.Builder(myActivity);
dialog.setMessage(“确认要清空所有数据吗”);
dialog.setPositiveButton(“确定”, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
SQLiteDatabase db = helper.getWritableDatabase();
String sql = “delete from collect where userId=”+userId;
db.execSQL(sql);
db.close();
Toast.makeText(myActivity, “删除成功”, Toast.LENGTH_SHORT).show();
loadData();
}
});
dialog.setNeutralButton(“取消”, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
dialog.show();
}
});
initView();
}
图3-53.3.3 修正个人信息模块信息public class PasswordActivity extends AppCompatActivity {
MySqliteOpenHelper helper = null;
private Activity activity;
private ActionBar mTitleBar;//标题栏
private EditText etEmail;
private EditText etNewPassword;
private Integer userId;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activity =this;
setContentView(R.layout.activity_password);
helper = new MySqliteOpenHelper(this);
userId = (Integer) SPUtils.get(activity,SPUtils.USER_ID,0);
etEmail = findViewById(R.id.et_email);
etNewPassword = findViewById(R.id.et_new_password);
mTitleBar = (ActionBar)findViewById(R.id.myActionBar);
mTitleBar.setData(activity,”重置密码”, R.drawable.ic_back, 0, 0,getResources().getColor(R.color.colorPrimary), new ActionBar.ActionBarClickListener() {
@Override
public void onLeftClick() {
finish();
}
@Override
public void onRightClick() {
}
});
}
图3-6
四、北京旅游系统的旅游攻略功能模块的详细设计4.1 旅游攻略模块的功能描述旅游攻略页面通过Fragment的办法放置在fragment_tab_home中的,fragment_tab_home利用了约束布局,在页面底部用了BottomNavigationView底部导航视图放置四个自定义的菜单导航按钮,用fragment标签添补页面内容,从而实现点击底部按钮跳转到相应fragment的功能,还有轮播图是实现以及图片的点击韶光,旅游攻略点点击以及页面跳转。
页面利用了适配器来显示旅游景点的信息,采取的是相对布局,在布局文件中将高度设置为wrap_content,用来确保适配器加载完毕后不会涌现一条数据独占一全体页面的情形,布局里面利用了一个ImageView和两个TextView来进行布局,定义轮播图居中显示和圆角的设定是页面更美化。
4.2 旅游攻略模块的界面布局的设计
图4-1protected void onCreate( Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myActivity = this;
setContentView(R.layout.activity_main);
MyApplication.Instance.setMainActivity(myActivity);
userId = (Integer) SPUtils.get(myActivity,SPUtils.USER_ID,0);
llContent = (LinearLayout) findViewById(R.id.ll_main_content);
rbStrategy = (RadioButton) findViewById(R.id.rb_main_strategy);
rbCommunity = (RadioButton) findViewById(R.id.rb_main_community);
rbUser = (RadioButton) findViewById(R.id.rb_main_user);
mActionBar = (ActionBar) findViewById(R.id.myActionBar);
//侧滑菜单
mActionBar.setData(myActivity,”旅游攻略”, 0, 0, 0, getResources().getColor(R.color.colorPrimary), new ActionBar.ActionBarClickListener() {
@Override
public void onLeftClick() {
}
@Override
public void onRightClick() {
}
});
initView();
setViewListener();
}
private void setViewListener() {
rbStrategy.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mActionBar.setTitle(“旅游攻略”);
switchFragment(0);
}
4.3 旅游攻略模块的Activity的设计
图4-2public class StrategyFragment extends Fragment {
MySqliteOpenHelper helper = null;
private Activity myActivity;//高下文
private RecyclerView rvList;
private StrategyAdapter strategyAdapter;
private LinearLayout llEmpty;
private EditText etQuery;//搜索内容
private ImageView ivSearch;//搜索图标
private List<Strategy> strategyList;
private Integer userId;
@Override
public void onAttach(Context context) {
super.onAttach(context);
myActivity = (Activity) context;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_strategy, container, false);
helper = new MySqliteOpenHelper(myActivity);
rvList = (RecyclerView) view.findViewById(R.id.rv_list);
llEmpty = view.findViewById(R.id.ll_empty);
etQuery = view.findViewById(R.id.et_query);
ivSearch = view.findViewById(R.id.iv_search);
//获取控件
initView();
//软键盘搜索
ivSearch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
loadData();//加载数据
}
});
//点击软键盘中的搜索
etQuery.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
loadData();//加载数据
return true;
}
return false;
}
});
return view;
}
图4-34.3.1旅游攻略的列表的实现
图4-4private void initView() {
userId = (Integer) SPUtils.get(myActivity, SPUtils.USER_ID, 0);
GridLayoutManager layoutManager = new GridLayoutManager(myActivity, 2);//两列
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
//=1.3、设置recyclerView的布局管理器
rvList.setLayoutManager(layoutManager);
HashMap<String, Integer> mapSpaces = new HashMap<>();//间距
mapSpaces.put(RecyclerViewSpaces.TOP_DECORATION, 20);//上间距
mapSpaces.put(RecyclerViewSpaces.BOTTOM_DECORATION, 20);//下间距
mapSpaces.put(RecyclerViewSpaces.LEFT_DECORATION, 20);//左间距
mapSpaces.put(RecyclerViewSpaces.RIGHT_DECORATION, 20);//右间距
rvList.addItemDecoration(new RecyclerViewSpaces(mapSpaces));//设置间距
//==2、实例化适配器
//=2.1、初始化适配器
strategyAdapter = new StrategyAdapter();
//=2.3、设置recyclerView的适配器
rvList.setAdapter(strategyAdapter);
loadData();
strategyAdapter.setItemListener(new StrategyAdapter.ItemListener() {
@Override
public void ItemClick(Strategy strategy) {
Intent intent = new Intent(myActivity, StrategyDetailActivity.class);
intent.putExtra(“strategy”, strategy);
startActivityForResult(intent, 100);
}
});
}
private void loadData() {
String contentStr = etQuery.getText().toString();//获取搜索内容
strategyList = new ArrayList<>();
Strategy strategy = null;
String sql = “select from strategy”;
if (!””.equals(contentStr)){
sql+=” where title like ?”;
}
SQLiteDatabase db = helper.getWritableDatabase();
Cursor cursor = db.rawQuery(sql,!””.equals(contentStr)?new String[]{“%”+contentStr+”%”}:null);
if (cursor != null && cursor.getColumnCount() > 0) {
while (cursor.moveToNext()) {
Integer dbId = cursor.getInt(0);
String title = cursor.getString(1);
String img = cursor.getString(2);
String content = cursor.getString(3);
String ticket = cursor.getString(4);
strategy = new Strategy(dbId,title, img, content, ticket);
strategyList.add(strategy);
}
}
Collections.reverse(strategyList);
if (strategyList != null && strategyList.size() > 0) {
rvList.setVisibility(View.VISIBLE);
llEmpty.setVisibility(View.GONE);
strategyAdapter.addItem(strategyList);
} else {
rvList.setVisibility(View.GONE);
llEmpty.setVisibility(View.VISIBLE);
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 100 && resultCode == RESULT_OK) {
loadData();//加载数据
}
}
}
4.3.2旅游攻略的菜单的实现
public class StrategyDetailActivity extends AppCompatActivity {
MySqliteOpenHelper helper = null;
private Activity mActivity;
private ImageView ivImg;
private TextView tvTitle;
private TextView tvTicket;
private TextView tvContent;
private EditText etContent;
private TextView tvLike;
private TextView tvCollect;
private ImageView ivvCollect;
private ImageView ivCollectCheck;
private ImageView ivLike;
private ImageView ivLikeCheck;
private ActionBar mActionBar;//标题栏
private SimpleDateFormat sf = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
private Integer userId;
private SQLiteDatabase db;
private Strategy strategy;
private LinearLayout llEmpty;
private RecyclerView rvList;
private CommentAdapter commentAdapter;
private List<Comment> commentList;
private int praiseCount = 0;//点赞数
private int collectCount = 0;//收藏数
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mActivity = this;
setContentView(R.layout.activity_strategy_detail);
helper = new MySqliteOpenHelper(this);
ivImg = findViewById(R.id.img);
tvTitle = findViewById(R.id.title);
tvTicket = findViewById(R.id.ticket);
tvContent = findViewById(R.id.content);
etContent = findViewById(R.id.et_content);
tvLike = findViewById(R.id.tv_like);
tvCollect = findViewById(R.id.tv_collect);
ivvCollect = findViewById(R.id.iv_collect);
ivCollectCheck = findViewById(R.id.iv_collect_check);
ivLike = findViewById(R.id.iv_like);
ivLikeCheck = findViewById(R.id.iv_like_check);
llEmpty = findViewById(R.id.ll_empty);
rvList = findViewById(R.id.rv_list);
mActionBar = findViewById(R.id.myActionBar);
//侧滑菜单
mActionBar.setData(mActivity, “明细信息”, R.drawable.ic_back, 0, 0, getResources().getColor(R.color.colorPrimary), new ActionBar.ActionBarClickListener() {
@Override
public void onLeftClick() {
finish();
}
@Override
public void onRightClick() {
}
});
userId = (Integer) SPUtils.get(mActivity, SPUtils.USER_ID, 0);
strategy = (Strategy) getIntent().getSerializableExtra(“strategy”);
tvTicket.setText(strategy.getTitle());
tvTitle.setText(String.format(“¥%s”, strategy.getTitle()));
tvContent.setText(strategy.getContent());
Glide.with(mActivity)
.asBitmap()
.skipMemoryCache(true)
.load(strategy.getImg())
.diskCacheStrategy(DiskCacheStrategy.NONE)
.into(ivImg);
db = helper.getWritableDatabase();
if (userId > 0) {//已登录
//查询点赞状态
String selectPraiseSql = “select from praise where articleId=” + strategy.getId() + ” and type=” + ArticleTypeEnum.Strategy.getCode() + ” and userId=” + userId;
Praise praise = null;
Cursor cursorPraise = db.rawQuery(selectPraiseSql, null);
if (cursorPraise != null && cursorPraise.getColumnCount() > 0) {
while (cursorPraise.moveToNext()) {
Integer dbId = cursorPraise.getInt(0);
Integer dbArticleId = cursorPraise.getInt(1);
Integer dbUserId = cursorPraise.getInt(2);
Integer dbType = cursorPraise.getInt(3);
praise = new Praise(dbId, dbArticleId, dbUserId, dbType);
}
}
图4-5
4.3.3 查找旅游攻略模块信息
图4-6
图4-7
private void getCommentList() {
String commentSql = “select c.,u.nickName from comment c,user u where c.userId = u.id and c.type=” + ArticleTypeEnum.Strategy.getCode() + ” and c.articleId=” + strategy.getId();
List<CommentVo> list = new ArrayList<>();
Cursor cursor1 = db.rawQuery(commentSql, null);
if (cursor1 != null && cursor1.getColumnCount() > 0) {
while (cursor1.moveToNext()) {
Integer dbId = cursor1.getInt(0);
Integer dbArticleId = cursor1.getInt(1);
Integer dbUserId = cursor1.getInt(2);
String dbContent = cursor1.getString(3);
String dbDate = cursor1.getString(4);
Integer dbType = cursor1.getType(5);
String nickName = cursor1.getString(6);
CommentVo comment = new CommentVo(dbId, dbArticleId, dbUserId, dbContent, dbDate, dbType, nickName);
list.add(comment);
}
}
if (list.size() > 0) {
commentAdapter.addItem(list);
rvList.setVisibility(View.VISIBLE);
llEmpty.setVisibility(View.GONE);
} else {
rvList.setVisibility(View.GONE);
llEmpty.setVisibility(View.VISIBLE);
}
}
//揭橥
public void publish(View view) {
if (userId == 0) {////未登录,跳转到登录页面
Toast.makeText(mActivity, “请登录后操作”, Toast.LENGTH_SHORT).show();
}else {//已经登录
String content = etContent.getText().toString();
if (“”.equals(content)) {
Toast.makeText(mActivity, “请输入查找内容”, Toast.LENGTH_SHORT).show();
return;
}
String insertSql = “insert into comment(articleId,userId,content,date,type) values(?,?,?,?,?)”;
db.execSQL(insertSql, new Object[]{strategy.getId(), userId, content, sf.format(new Date()), ArticleTypeEnum.Strategy.getCode()});
Toast.makeText(mActivity, “成功”, Toast.LENGTH_SHORT).show();
etContent.setText(“”);
getCommentList();
}
}
}
图4-8
五、系统测试5.1 登录功能模块测试5.1.1软件的测试环境软硬件哀求:系统环境 win7;硬件系统环境core i3、3G内存、500G硬盘。此外对其他软件险些没有依赖性,程序健壮性较好。
5.1.2测试建立一张仿照的SD卡,上传软件;测试软件的注册登录功能用户体验是否良好。
5.1.3测试阶段按照软件测试的策略和过程分类,软件测试可分为单元测试、集成测试、确认测试、系统测试和验收测试。它们被依次顺序地实行,此模块实验紧张是进行功能测试。
5.1.4测试结果此北京旅游攻略软件登录模块用户体验良好,基本符合设计哀求。
5.2 景点攻略功能模块测试5.2.1 软件的测试环境软硬件哀求:系统环境 win7;硬件系统环境core i3、3G内存、500G硬盘。此外对其他软件儿乎没有依赖性,程序健壮性较好。
5.2.2测试建立一张仿照的SD卡,上传软件;测试软件的景点攻略功能是否能无缺查看、还有在线查看门票价格、在线评论功能是否顺畅、用户体验是否良好。
5.2.3软件测试的评价软件功能评价:此北京旅游攻略软件景点攻略模块用户体验良好,基本符合设计哀求。
结论:此软件的设计和论证是可行的。
5.2.4测试阶段软件测试工程量大、过程繁芜,在全体软件开拓周期中霸占着举足轻重的地位,需求调研和软什测试霸占了软件开拓三分之二韶光。此模块实验紧张是进行功能测试。
5.2.5测试结果在课题后期进行了大力度的软件测试,按照测试的流程和规则,紧张进行了功能测试。软件紧张的 bug 表现为闪退、卡去世等征象,在器上不雅观看log则能创造紧张问题是运行时非常。我们紧张对bug采纳了非常拦截的办法进行调试完善,测试完成后软件稳定运行。
5.3 社区评论功能模块测试5.3.1软件的测试环境软硬件哀求:系统环境 win7;硬件系统环境core i3、3G内存、500G硬盘。此外对其他软件儿乎没有依赖性,程序健壮性较好。
5.3.2测试建立一张仿照的SD卡,上传软件;测试软件的社区评论功能用户体验是否良好。
5.3.3测试阶段对付软什测试我们须要从不同的角度考虑,明确测试的目的,风雅化测试的过程,对测试过程进行明确的分类,制订好测试操持,只管即便做到细致以及全面的测试。此模块实验紧张是进行功能测试。
5.3.4测试结果此北京旅游攻略软件社区评论模块用户体验良好,基本符合设计哀求。
六、项目总结本文紧张是对Android平台北京旅游攻略的剖析设计,紧张实现了景点先容、在线评论、景点购票、旅行日记、景点收藏、个人登录退出等功能。在本文中第一章简要的先容了课题目前背景、研究现状等;第二章中讲述了Android的系统剖析与概要设计;第三章进行了详尽的登录模块功能剖析;第四章进行详细设计以及编码实现事情;末了的第五章进行了软件的测试事情,完善软件。本设计的北京旅游攻略软件能够稳定运行,体积小且反响灵敏,但还是有几点不敷的地方,例如最近查看旅游景点无法排序、代码编写冗余重复率高、图片素材布局不太都雅等等。在往后我会改进软件的不敷,以更优的编码水平,更高超的布局思维模型,并且学习更多新的知识重构这款软件。这款北京旅游攻略软件还是比较好的,适用于智好手机市场,有良好的用户体验和反应速率。相信随着智好手机在发展中国家的遍及,它们市场上会拥有弘大的用户群。
七、参考文献[1]王兴中.中国旅游资源开拓模式与旅游区域可持续发展理念[J.地理科学,2014,24 (1) : 51-58.
[2]王慧云.旅游教诲与旅游业可持续发展[J].桂林旅游高档专科学校学报,2015,32(3) : 101-106.
[3]章锦河.中国国际旅游业与国际贸易比较研究〔J.安徽师大学报,2014,17 (2) : 101-106.
[4]柯元旦. Android内核阐发[M].北京:电子工业出版社,2012: 59-70.
[5]丰生强. Android软件安全与逆向剖析[M].北京:公民邮电出版社,2013:78-90.
[6]余成锋,李代平,毛永华. Android3.0内存管理机制剖析[M].北京:北京公民
邮电出版社,2013: 55-80.
[7]佐冰冰. Android平台下Launcher启动器的设计与实现[D].哈尔滨:哈尔滨工业大学博士学位论文. 2012: 4-9.
[8]杜吉志,徐明昆. Android系统内存管理研究及优化[J].软件工程,2012,24 (5): 69-80.
[9]高巍. Android操作系统软件自动化测试方案的设计与履行[D].北京:北京邮电大学博士学位论文.2014: 8-14.
[10〕孙剑. Android系统上运用程序按需加载机制的设计与实现 [M].北京:北京大学出版社,2014: 99-110.
[11]卢娜.基于Android平台的手机桌面资讯系统的设计与实现〔M].西安:西安电子科技大学出版社,2012: 290-300.
(注:此页为报告内容末页,打印在单面,与报告装订在一起)
课程报告评分:
评分点 得分报告格式和排版(10分)系统概要设计(20分)系统详细设计(20分)系统测试(20分)总结(10分)代码注释(20分)总分(100分)加分项(10分)辅导西席具名:
年 月 日