文章目录
案例说明实现案例视频
UI布局UI效果activity_main.xml文件代码tostrings.xml文件代码
书本类和用户类的定义书本类Book用户类Person
功能实现初始化控件findViews()初始化数据initData()添加监听器setListeners()mNameEditText监听器mLendEditText监听器mSexRadioGroup监听器三个CheckBox的监听器SeekBar监听器mQueryButton监听器mNextButton监听器
查找书籍方法主体日期比较方法主体
案例说明
这个是我初学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,类型kindint:适用年龄age,图片的地址picboolean:是否属于历史、悬疑、文艺
public class Book {
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
;
}
}
用户类Person
根据要求,书本类属性包括以下属性
String:姓名name,性别sexint:年龄ageDate:借书时间lendTimeBook:书本类对象book
public class Person {
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
;
}
}
用户在UI界面输入的借书时间是String类型,不能通过Person类原始的setLendTime方法直接传参,需要将传进来的字符串进行格式转换
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的功能以及部分控件设置初始值操作
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
);
mSeekBar
.setProgress(20);
mAgeTextView
= findViewById(R
.id
.seekBar_ageTextView
);
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属性
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
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进行赋值
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的监听器
存储用户的阅读喜好
mHisCheckBox
.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView
, boolean isChecked
) {
mIsHistory
= isChecked
;
}
});
mSusCheckBox
.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView
, boolean isChecked
) {
mIsSuspense
= isChecked
;
}
});
mLitCheckBox
.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView
, boolean isChecked
) {
mIsLiterature
= isChecked
;
}
});
SeekBar监听器
这里只需获取用户滑动结果,并通过Toast来显示结果 mAge用户选择的年龄int类型 mAgeTextView是位于SeekBar左边的TextView控件,内容与当前选择的年龄一致
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
);
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();
mBookName
.setText(mBookResult
.get(mCurrentIndex
).getName());
mBookAge
.setText(String
.valueOf(mBookResult
.get(mCurrentIndex
).getAge()));
mBookKind
.setText(mBookResult
.get(mCurrentIndex
).getKind());
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());
mBookName
.setText(mBookResult
.get(mCurrentIndex
).getName());
mBookAge
.setText(String
.valueOf(mBookResult
.get(mCurrentIndex
).getAge()));
mBookKind
.setText(mBookResult
.get(mCurrentIndex
).getKind());
mBookNumTextView
.setText("符合条件的书还剩" + (mBookResult
.size() - 1) + "本");
}
}
日期比较方法主体
private boolean compareDate() {
if (lend
.compareTo(borrow
) == 1)
return true;
else
return false;
}
IDE:Android Studio 4.0