Android图书管理系统
开发环境:Android Studio
通过输入书名查询图书,效果如下
HomeFragment.java
package com.example.myapplication.ui.login.ui.home;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.EditText;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.alibaba.fastjson.JSON;
import com.example.myapplication.R;
import com.example.myapplication.data.model.Book;
import com.example.myapplication.data.model.HttpUtils;
import com.example.myapplication.ui.login.LogActivity;
import com.example.myapplication.ui.login.Main2Activity;
import com.example.myapplication.util.ToastUtil;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import okhttp3.Call;
import okhttp3.Response;
public class HomeFragment extends Fragment {
//private HomeViewModel homeViewModel;
private RecyclerView rv_bookList;
private EditText et_bookName;
private List<Book> bookList = new ArrayList<>();
private BookListAdapter mAdapter;
private String urlPath;
private int totalCount;
class MyDecoration extends RecyclerView.ItemDecoration{
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
outRect.set(0,0,0,getResources().getDimensionPixelOffset(R.dimen.divider_height));
}
}
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_borrow_book, container, false);
rv_bookList = rootView.findViewById(R.id.rv_booklist);
et_bookName = rootView.findViewById(R.id.et_bookName);
initView();
et_bookName.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) {
initData(s.toString());
}
@Override
public void afterTextChanged(Editable s) {
}
});
return rootView;
}
public Handler handler=new Handler(){
@SuppressLint("HandlerLeak")
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 1:
initView();
break;
default:
throw new IllegalStateException("Unexpected value: " + msg.what);
}
}
};
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
/*
* 初始化数据
* */
public void initData(String bookName){
new Thread(){
@Override
public void run() {
queryByBookNameFromClient(bookName);
}
}.start();
}
/*
* 初始化视图
* */
public void initView(){
//默认分割线
//rv_bookList.addItemDecoration(new DividerItemDecoration(getContext(),DividerItemDecoration.VERTICAL));
//自定义分割线
DividerItemDecoration divider = new DividerItemDecoration(getContext(),DividerItemDecoration.VERTICAL);
divider.setDrawable(ContextCompat.getDrawable(getContext(),R.drawable.custom_divider));
rv_bookList.addItemDecoration(divider);
mAdapter = new BookListAdapter(bookList);
rv_bookList.setLayoutManager(new LinearLayoutManager(getActivity()));
rv_bookList.setAdapter(mAdapter);
}
private void queryByBookNameFromClient(String bookName){
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("name", bookName);
} catch (JSONException e) {
e.printStackTrace();
}
urlPath = "http://192.168.1.117:8080/emp_ssm/book/queryByBookNameFromClient.action";
//使用okhtttp连接服务器 post发送请求
HttpUtils.sendHttpRequestPost(urlPath, jsonObject.toString(),new okhttp3.Callback() {
@Override
public void onFailure(Call call, IOException e) {
Looper.prepare();
ToastUtil.showToast(getContext(),"连接失败");
Looper.loop();
Log.e("okhttpOnFailer", "连接失败");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (bookList == null) {
bookList = new ArrayList<Book>();
}
bookList.clear();
String responseData = response.body().string();
Log.e("responseData", responseData);
Map<String, Object> map = JSON.parseObject(responseData, Map.class);
bookList = getBookList((List) map.get("listDate"));
totalCount = (int) map.get("totalCount");
//使用handler调用视图更新
handler.sendEmptyMessage(1);
Log.e("bookList", bookList.toString());
Log.e("totalCount", String.valueOf(totalCount));
}
});
}
/**
*
* 把 json 数组转换为 List<Book>
* @return
*/
public List<Book> getBookList(List arr)
{
List<Book> list = new ArrayList<>();
for (int i = 0; i < arr.size(); i++)
{
Map<String,Object> map = new HashMap<>();
Book book = new Book();
map = (Map<String, Object>) arr.get(i);
book.setId((String) map.get("id"));
book.setName((String) map.get("name"));
list.add(book);
}
return list;
}
}
BookListAdapter.java
package com.example.myapplication.ui.login.ui.home;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.myapplication.R;
import com.example.myapplication.data.model.Book;
import com.example.myapplication.util.ToastUtil;
import java.util.List;
public class BookListAdapter extends RecyclerView.Adapter<BookListAdapter.BookListViewHolder> {
private List<Book> bookList;
public BookListAdapter(List<Book> bookList){
this.bookList = bookList;
}
@NonNull
@Override
public BookListAdapter.BookListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from (parent.getContext()).inflate (R.layout.borrowbooklist_item_layout,parent,false);
BookListViewHolder holder = new BookListViewHolder (view);
return holder;
}
@Override
public void onBindViewHolder(@NonNull BookListAdapter.BookListViewHolder holder, int position) {
Book book = bookList.get(position);
holder.tv_bookName.setText(book.getName());
holder.tv_bookISBN.setText("ISBN: "+book.getId());
//holder.tv_remainBookNum.setText(book.getName());
//holder.tv_allBookNum.setText(book.getName());
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ToastUtil.showToast(v.getContext(),"click:"+book.getName());
}
});
}
@Override
public int getItemCount() {
return bookList.size();
}
class BookListViewHolder extends RecyclerView.ViewHolder{
private TextView tv_bookName;
private TextView tv_bookISBN;
private TextView tv_remainBookNum;
private TextView tv_allBookNum;
public BookListViewHolder(@NonNull View itemView) {
super(itemView);
tv_bookName = itemView.findViewById(R.id.tv_bookName);
tv_bookISBN = itemView.findViewById(R.id.tv_bookISBN);
tv_remainBookNum = itemView.findViewById(R.id.tv_remainBookNum);
tv_allBookNum = itemView.findViewById(R.id.tv_allBookNum);
}
}
}
Book.java
package com.example.myapplication.data.model;
public class Book {
private String id;
private String name;
private int type_id;
private int status;
private int count;
//此处添加getter、setter
}
HttpUtils.java
package com.example.myapplication.data.model;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
public class HttpUtils {
public static final MediaType JSON= MediaType.parse("application/json; charset=utf-8");
public static void sendHttpRequest(String address,okhttp3.Callback callback){
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(address)
.build();
client.newCall(request).enqueue(callback);
}
public static void sendHttpRequestPost(String path, String json, okhttp3.Callback callback) {
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = RequestBody.create(JSON ,json);
Request request = new Request.Builder()
.url(path)
.post(requestBody)
.build();
client.newCall(request).enqueue(callback);
}
}
ToastUtil.java(可以解决连续点击导致Toast显示时间较长的问题)
package com.example.myapplication.util;
import android.content.Context;
import android.widget.Toast;
public class ToastUtil {
public static Toast toast;
public static void showToast(Context contex,String msg){
if(toast==null){
toast = Toast.makeText(contex,msg,Toast.LENGTH_SHORT);
}else{
toast.setText(msg);
}
toast.show();
}
}
fragment_borrow_book.xml
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.circularreveal.CircularRevealRelativeLayout 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:orientation="horizontal"
tools:context=".ui.login.ui.home.HomeFragment">
<EditText
android:id="@+id/et_bookName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:ignore="MissingConstraints"
android:hint="请输入书名"
android:textSize="30sp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_booklist"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/et_bookName">
</androidx.recyclerview.widget.RecyclerView>
</com.google.android.material.circularreveal.CircularRevealRelativeLayout>
borrowbooklist_item_layout.xml
<?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:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="10">
<TextView
android:id="@+id/tv_bookName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000"
android:text="图书名称"
android:textSize="20sp">
</TextView>
<TextView
android:id="@+id/tv_bookISBN"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000"
android:layout_below="@+id/tv_bookName"
android:text="ISBN:"
android:textSize="20sp">
</TextView>
</RelativeLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
>
<TextView
android:id="@+id/tv_remainBookNum"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000"
android:text="剩余xx本,"
android:textSize="15sp">
</TextView>
<TextView
android:id="@+id/tv_allBookNum"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000"
android:text="总共xx本"
android:textSize="15sp">
</TextView>
</LinearLayout>
</LinearLayout>
自定义分割线布局:custom_divider.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#ffff0000"
android:centerColor="#ff00ff00"
android:endColor="#ff0000ff"
android:type="linear" />
<size android:height="0.5dp" />
</shape>
下面附上SpringMVC的代码:
BookController.java
package com.zhiyou100.controller;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.zhiyou100.pojo.Book;
import com.zhiyou100.service.BookService;
import com.zhiyou100.service.BorrowBookService;
@Controller
@RequestMapping("/book")
public class BookController {
@Autowired
private BookService bookService;
@Autowired
private BorrowBookService borrowBookService;
@RequestMapping( value="/queryByBookNameFromClient",method={RequestMethod.POST,RequestMethod.GET})
@ResponseBody
public Map<String,Object> queryByBookNameFromClient(@RequestBody Book book) {
System.out.println("bookname:"+book.getName());
int totalCount = bookService.selectBookCountFromClient(book.getName());
Map<String,Object> map = new HashMap<String, Object>();
List<Book> bookList=new ArrayList<Book>();
try {
bookList=bookService.selectByBookNameFromClient(book.getName());
map.put("listDate", bookList);
map.put("totalCount", totalCount);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(map.toString());
return map;
}
}