Android-UI 借书界面

    技术2024-03-09  68

    文章目录

    案例说明实现案例视频 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 { //属性:书名、类型、适用年龄、图片地址 //三个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,性别sexint:年龄ageDate:借书时间lendTimeBook:书本类对象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

    Processed: 0.024, SQL: 9