荐 Android 借书UI界面
文章目录
案例说明
这个是我初学Android开发的时候用Java做的一个借书Demo,因为没有学数据库所以不包含数据库相关的技术,直接在代码中完成书籍的实例化操作
实现
- 完成UI界面搭建
- 完成书籍的查找并显示功能
- 完成书籍信息的“下一页”显示功能
- 完成借书时间判断功能
- 输入的时间格式要按照演示视频的格式输入,并将输入的时间格式化成(yyyy-MM-dd)的形式
- 判断日期,如果借出日期晚于还书日期,则弹出提示信息并调用finish()方法实现页面的关闭,当输入时间符合要求时则能正确查找图书
案例视频
UI布局
布局约束用的是线性布局LinearLayout,这一块基本没有什么难度,无非就是各个LinearLayout之间控制好权重属性android:layout_weight,具体的细节完全按照自己喜好来就可以
UI效果
activity_main.xml文件代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFB4EA"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="@string/title"
android:textColor="#AA5E91"
android:textSize="26sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="10dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="@string/nametext"
android:textSize="18sp"
android:textStyle="bold" />
<EditText
android:id="@+id/nameEditText"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginLeft="30dp"
android:layout_weight="1"
android:hint="@string/inputname_hint"
android:textSize="14dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:text="@string/sextext"
android:textSize="18sp"
android:textStyle="bold" />
<RadioGroup
android:id="@+id/sexRadioGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioButton
android:id="@+id/male"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/male"
android:textSize="18sp" />
<RadioButton
android:id="@+id/female"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/female"
android:textSize="18sp" />
</RadioGroup>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="@string/lendtimetext"
android:textSize="18sp"
android:textStyle="bold" />
<EditText
android:id="@+id/lendEditText"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:hint="@string/inputlendtime_hint"
android:textSize="14dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/returntimetext"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="@+id/returnTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/returntime"
android:textSize="16sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="@string/hobbytext"
android:textSize="18sp"
android:textStyle="bold" />
<CheckBox
android:id="@+id/hisCheckBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:text="@string/historytext"
android:textSize="18sp" />
<CheckBox
android:id="@+id/susCheckBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:text="@string/suspensetext"
android:textSize="18sp" />
<CheckBox
android:id="@+id/litCheckBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/literaturetext"
android:textSize="18sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="@string/agetext"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="@+id/seekBar_ageTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:textSize="18sp" />
<SeekBar
android:id="@+id/seekBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_weight="1" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:text="@string/age_100"
android:textSize="18sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_weight="3"
android:background="#FFD4EE"
android:orientation="horizontal">
<ImageView
android:id="@+id/bookImageView"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:src="@mipmap/f" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="10dp">
<TextView
android:id="@+id/bookNameTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="15dp"
android:text="@string/bookname"
android:textSize="16sp" />
<TextView
android:id="@+id/bookKindTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="15dp"
android:text="@string/kind"
android:textSize="16sp" />
<TextView
android:id="@+id/bookAgeTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/age"
android:textSize="16sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal"
android:padding="10dp">
<Button
android:id="@+id/queryBtn"
android:layout_width="100dp"
android:layout_height="50dp"
android:background="#CC91BD"
android:text="@string/querybtntext"
android:textColor="#593152"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="@+id/bookNumTextView"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginTop="-10dp"
android:layout_marginRight="20dp" />
<Button
android:id="@+id/nextBtn"
android:layout_width="100dp"
android:layout_height="50dp"
android:background="#CC91BD"
android:text="@string/next"
android:textColor="#593152"
android:textSize="20sp"
android:textStyle="bold" />
</LinearLayout>
</LinearLayout>
tostrings.xml文件代码
<resources>
<string name="app_name">LibraryDemo</string>
<string name="title">借书</string>
<string name="nametext">读者:</string>
<string name="inputname_hint">请输入名字</string>
<string name="sextext">性别:</string>
<string name="male">男</string>
<string name="female">女</string>
<string name="lendtimetext">借出时间:</string>
<string name="inputlendtime_hint">请输入</string>
<string name="returntimetext">归还时间:</string>
<string name="returntime">2016.06.30</string>
<string name="hobbytext">爱好:</string>
<string name="historytext">历史</string>
<string name="suspensetext">悬疑</string>
<string name="literaturetext">文艺</string>
<string name="agetext">年龄:</string>
<string name="age_18">18</string>
<string name="age_100">100</string>
<string name="bookname">书名</string>
<string name="kind">类型</string>
<string name="age">适用年龄</string>
<string name="querybtntext">查找</string>
<string name="next">下一个</string>
</resources>
书本类和用户类的定义
书本类Book
根据要求,书本类属性包括以下属性
- String:书名name,类型kind
- int:适用年龄age,图片的地址pic
- boolean:是否属于历史、悬疑、文艺
public class Book {
//属性:书名、类型、适用年龄、图片地址
//三个boolean类型:历史、悬疑、文艺
private String name;
private String kind;
private int age;
private int pic;
boolean his;
boolean sus;
boolean lit;
public Book() {
}
public Book(String name, String kind, int age, int pic, boolean his, boolean sus, boolean lit) {
this.name = name;
this.kind = kind;
this.age = age;
this.pic = pic;
this.his = his;
this.sus = sus;
this.lit = lit;
}
//getter和setter方法...
}
用户类Person
根据要求,书本类属性包括以下属性
- String:姓名name,性别sex
- int:年龄age
- Date:借书时间lendTime
- Book:书本类对象book
public class Person {
//属性:姓名、性别、借书时间、书本
//年龄默认为20岁
private String name;
private String sex;
private int age = 20;
private Date lendTime;
private Book book;
public Person() {
}
public Person(String name, String sex, int age, Date lendTime, Book book) {
this.name = name;
this.sex = sex;
this.age = age;
this.lendTime = lendTime;
this.book = book;
}
//getter和setter方法...
}
用户在UI界面输入的借书时间是String类型,不能通过Person类原始的setLendTime方法直接传参,需要将传进来的字符串进行格式转换
//将输入的时间(String类型)转换为Date类型,格式"yyyy-MM-dd"
public void setLendTime(String dateString) throws ParseException {
this.lendTime = new SimpleDateFormat("yyyy-MM-dd").parse(dateString);
}
功能实现
首先确定onCreate方法的实现思路
为了代码的可读性,我把功能实现都封装在了方法体内
- 加载布局文件setContentView()
- 初始化控件findViews()
- 初始化数据initData()
- 为控件添加监听器并实现基本功能setListeners()
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化控件
findViews();
//初始化数据
initData();
//为控件添加监听器,实现基本功能
setListeners();
}
添加布局文件的方法在创建工程的时候已经自动生成了,所以就不用另外再写一遍
初始化控件findViews()
在这个方法体实现了获取控件ID的功能以及部分控件设置初始值操作
//初始化控件,获取控件ID
private void findViews() {
mNameEditText = findViewById(R.id.nameEditText);
mLendEditText = findViewById(R.id.lendEditText);
mSexRadioGroup = findViewById(R.id.sexRadioGroup);
mHisCheckBox = findViewById(R.id.hisCheckBox);
mSusCheckBox = findViewById(R.id.susCheckBox);
mLitCheckBox = findViewById(R.id.litCheckBox);
mSeekBar = findViewById(R.id.seekBar);
//设置SeekBar的初始值为20
mSeekBar.setProgress(20);
mAgeTextView = findViewById(R.id.seekBar_ageTextView);
//设置SeekBar控件左边的TextView显示的数值与SeekBar当前数值保持一致
mAgeTextView.setText(String.valueOf(mSeekBar.getProgress()));
mQueryButton = findViewById(R.id.queryBtn);
mNextButton = findViewById(R.id.nextBtn);
mBookImageView = findViewById(R.id.bookImageView);
mBookNumTextView = findViewById(R.id.bookNumTextView);
mBookName = findViewById(R.id.bookNameTextView);
mBookKind = findViewById(R.id.bookKindTextView);
mBookAge = findViewById(R.id.bookAgeTextView);
mReturnTime = findViewById(R.id.returnTime);
}
这里有个小技巧,在完成声明后选择该行按Ctrl+Alt+F,可以将声明操作提取成私有全局变量
private EditText mNameEditText;
private RadioGroup mSexRadioGroup;
private CheckBox mHisCheckBox;
private CheckBox mSusCheckBox;
private CheckBox mLitCheckBox;
private SeekBar mSeekBar;
private Button mQueryButton;
private Button mNextButton;
private ImageView mBookImageView;
private List<Book> mBooks;
private Person mPerson;
private List<Book> mBookResult;
private boolean mIsHistory;
private boolean mIsSuspense;
private boolean mIsLiterature;
private int mAge;
private int mCurrentIndex;
private TextView mAgeTextView;
private TextView mBookNumTextView;
private TextView mBookName;
private TextView mBookAge;
private TextView mBookKind;
private EditText mLendEditText;
private TextView mReturnTime;
private Date lend = null;
private Date borrow = null;
初始化数据initData()
工程不包含数据库方面的技术,这里通过initData方法初始化所有书本对象的信息,并且把它加入到mBooks
集合中mBookResult
符合条件的书本集合borrow
还书时间,这里把时间直接写死了,也可以通过其它方法来获取当前系统的时间
//初始化数据
private void initData() {
//初始化书本集合
mBooks = new ArrayList<Book>();
mBooks.add(new Book("人生感悟", "心灵鸡汤", 43, R.mipmap.aa, false, false, true));
mBooks.add(new Book("边城", "文学", 30, R.mipmap.bb, false, false, true));
mBooks.add(new Book("sapir", "传记", 28, R.mipmap.cc, true, false, true));
mBooks.add(new Book("光辉岁月", "历史", 50, R.mipmap.dd, true, false, false));
mBooks.add(new Book("宋词三百首", "诗文", 88, R.mipmap.ee, false, false, true));
mBooks.add(new Book("中国古代文学", "教学纲要", 42, R.mipmap.ff, false, false, true));
mBooks.add(new Book("无花果", "诗文", 35, R.mipmap.gg, false, false, true));
mBooks.add(new Book("古镇记忆", "悬疑", 22, R.mipmap.hh, true, true, false));
//始化用户对象
mPerson = new Person();
//初始化书本查找集合
mBookResult = new ArrayList<Book>();
//初始化还书时间
try {
borrow = new SimpleDateFormat("yyyy-MM-dd").parse("2016-06-30");
} catch (ParseException e) {
e.printStackTrace();
}
}
添加监听器setListeners()
这一块是整个Demo的核心代码,大部分控件的响应事件都封装在这里
//为控件添加监听器
private void setListeners() {
mNameEditText监听器
将用户输入的姓名字符串传给mPerson
对象的setName方法修改mPerson
的name
属性
//nameEditText监听器
mNameEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (mPerson != null)
mPerson.setName(s.toString());
}
});
传参之前先判断一下是否为空避免崩溃
mLendEditText监听器
将用户输入的时间字符串传给mPerson
对象的setLendTime方法修改mPerson
的lendTime
属性,并将lendTime
赋值给this.lend
//lendEditText监听器
mLendEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (mPerson != null) {
try {
mPerson.setLendTime(s.toString());
} catch (ParseException e) {
e.printStackTrace();
}
}
lend = mPerson.getLendTime();
}
});
传参时同样要判断对象是否为空
mSexRadioGroup监听器
性别选择的RadioButton放在一个RadioGroup里面,通过监听用户的选择给mPerson.sex
进行赋值
//RadioGroup监听器
mSexRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.male:
mPerson.setSex(getString(R.string.male));
break;
case R.id.female:
mPerson.setSex(getString(R.string.female));
break;
}
}
});
三个CheckBox的监听器
存储用户的阅读喜好
//hisCheckBox监听器
mHisCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mIsHistory = isChecked;
}
});
//susCheckBox监听器
mSusCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mIsSuspense = isChecked;
}
});
//litCheckBox监听器
mLitCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mIsLiterature = isChecked;
}
});
SeekBar监听器
这里只需获取用户滑动结果,并通过Toast
来显示结果mAge
用户选择的年龄int类型mAgeTextView
是位于SeekBar左边的TextView控件,内容与当前选择的年龄一致
//seekBar监听器
mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
mAge = seekBar.getProgress();
mPerson.setAge(mAge);
//SeekBar左边的TextView更新为当前年龄
mAgeTextView.setText(String.valueOf(mSeekBar.getProgress()));
Toast.makeText(MainActivity.this, "年龄:" + mAge, Toast.LENGTH_SHORT).show();
}
});
mQueryButton监听器
//查找按钮监听器
mQueryButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//格式化显示输入的借书时间
mLendEditText.setText(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(lend));
//每次查找前初始化图片及文字信息
mBookImageView.setImageResource(R.mipmap.f);
mBookName.setText(R.string.bookname);
mBookKind.setText(R.string.kind);
mBookAge.setText(R.string.age);
mBookNumTextView.setText("");
if (mPerson.getName() == null)
Toast.makeText(MainActivity.this, "姓名不能为空!", Toast.LENGTH_SHORT).show();
else if (mPerson.getLendTime() == null)
Toast.makeText(MainActivity.this, "借书日期不能为空!", Toast.LENGTH_SHORT).show();
else if (mPerson.getSex() == null)
Toast.makeText(MainActivity.this, "请选择性别!", Toast.LENGTH_SHORT).show();
else if (compareDate()) {//判断借出时间是否大于归还时间
Toast.makeText(MainActivity.this, "借书时间晚于还书时间,程序退出!", Toast.LENGTH_SHORT).show();
finish();
} else
searchBook();
}
});
mNextButton监听器
//下一个按钮监听器
mNextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mCurrentIndex++;
if (mCurrentIndex < mBookResult.size()) {
mBookImageView.setImageResource(mBookResult.get(mCurrentIndex).getPic());
Toast.makeText(MainActivity.this, "显示:Person[per_name=" + mPerson.getName()
+ ",sex=" + mPerson.getSex() + ",age=" + mPerson.getAge()
+ ",time=" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(lend) + "]"
, Toast.LENGTH_SHORT).show();
//ImageView右边显示书籍信息
mBookName.setText(mBookResult.get(mCurrentIndex).getName());
mBookAge.setText(String.valueOf(mBookResult.get(mCurrentIndex).getAge()));
mBookKind.setText(mBookResult.get(mCurrentIndex).getKind());
//按钮右边的TextView显示剩余数量
mBookNumTextView.setText("符合条件的书还剩" + (mBookResult.size() - mCurrentIndex - 1) + "本");
} else {
Toast.makeText(MainActivity.this, "没有啦!", Toast.LENGTH_SHORT).show();
}
}
});
查找书籍方法主体
//查找书籍
private void searchBook() {
//如果为空,先初始化书籍结果对象
if (mBookResult == null)
mBookResult = new ArrayList<Book>();
//清空结果列表
mBookResult.clear();
mCurrentIndex = 0;
//遍历所有书籍
for (int index = 0; index < mBooks.size(); index++) {
Book book = mBooks.get(index);
//适用年龄要大于设定年龄
//符合爱好的选择
if (book != null) {
if (book.getAge() >= mAge
&& ((book.isHis() == true) && (book.isHis() == mIsHistory)
|| (book.isLit() == true) && (book.isLit() == mIsLiterature)
|| (book.isSus() == true) && (book.isSus() == mIsSuspense))) {
mBookResult.add(book);
}
}
}
if (mCurrentIndex < mBookResult.size()) {
//先显示第一张图片
mBookImageView.setImageResource(mBookResult.get(mCurrentIndex).getPic());
//ImageView右边显示书籍信息
mBookName.setText(mBookResult.get(mCurrentIndex).getName());
mBookAge.setText(String.valueOf(mBookResult.get(mCurrentIndex).getAge()));
mBookKind.setText(mBookResult.get(mCurrentIndex).getKind());
//按钮右边的TextView显示剩余数量
mBookNumTextView.setText("符合条件的书还剩" + (mBookResult.size() - 1) + "本");
}
}
日期比较方法主体
//日期比较
private boolean compareDate() {
//若借书时间晚于还书时间,返回true
if (lend.compareTo(borrow) == 1)
return true;
else
return false;
}
IDE:Android Studio 4.0
本文地址:https://blog.csdn.net/lckgr/article/details/107111464