1、引言
终于修改到书架界面和历史阅读记录界面了,修改完这两个界面就算完成一大半了,这两个界面其实都差不多,代码逻辑都一样,因此后面也会只展示书架界面的代码,历史阅读记录界面就展示效果图就行了。
2、实现代码
2.1、书架界面主布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/rl_shelf"
android:background="#ffffff">
<RelativeLayout
android:id="@+id/rl_book_top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#00000000"
android:layout_marginTop="10dp">
<TextView
android:id="@+id/tv_book"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginVertical="10dp"
android:layout_marginLeft="10dp"
android:text="书架"
android:textColor="#303030"
android:textSize="20sp"
android:textStyle="bold" />
<ImageView
android:id="@+id/iv_search"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_marginRight="35dp"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:background="@drawable/search_shelf"/>
<TextView
android:id="@+id/tv_exit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:layout_marginRight="35dp"
android:text="退出管理"
android:textColor="#303030"
android:visibility="gone"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"/>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/rl_book_top"
android:orientation="vertical">
<ImageView
android:id="@+id/iv_shelf_line"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#c5c5c5"/>
<GridView
android:id="@+id/gv_shelf"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="15dp"
android:verticalSpacing="10dp"
android:numColumns="3">
</GridView>
</LinearLayout>
<RelativeLayout
android:id="@+id/Rl_book_bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#f5f5f5"
android:visibility="gone"
android:layout_alignParentBottom="true">
<TextView
android:id="@+id/tv_book_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="全选"
android:textSize="20sp"
android:layout_marginLeft="15dp"
android:layout_marginVertical="15dp"
android:layout_centerVertical="true"
android:textColor="#606060"/>
<TextView
android:id="@+id/tv_book_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="删除"
android:textSize="20sp"
android:layout_marginRight="15dp"
android:layout_centerVertical="true"
android:textColor="#ff0000"/>
</RelativeLayout>
</RelativeLayout>
2.2、书架界面实际布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff">
<ImageView
android:id="@+id/iv_grid"
android:layout_width="90dp"
android:layout_height="125dp"
android:layout_centerHorizontal="true"
android:background="@drawable/empty"/>
<LinearLayout
android:id="@+id/ll_content"
android:layout_width="100dp"
android:layout_below="@+id/iv_grid"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:gravity="center_horizontal">
<TextView
android:id="@+id/tv_grid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:layout_marginTop="5dp"
android:textColor="#303030"
android:text="书名"/>
</LinearLayout>
<ImageView
android:id="@+id/iv_select"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_alignBottom="@+id/iv_grid"
android:layout_alignRight="@+id/iv_grid"
android:layout_marginRight="5dp"
android:layout_marginBottom="5dp"
android:visibility="gone"
android:background="@drawable/checkbox_ic_default"/>
</RelativeLayout>
2.3、逻辑代码
在这里其实还要配合上次阅读界面那里添加书架和历史记录查看,但上次那里没修改,不过没太大变化,可以参考上次阅读界面那里。
package xyz.dritrtj.read.fragment;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import xyz.dritrtj.read.R;
import xyz.dritrtj.read.base.BaseFragment;
import xyz.dritrtj.read.data.Title;
import xyz.dritrtj.read.ui.MainActivity;
import xyz.dritrtj.read.ui.ReadActivity;
import xyz.dritrtj.read.ui.SearchActivity;
import xyz.dritrtj.read.utils.DBHelper;
import xyz.dritrtj.read.utils.SetUiSize;
import java.util.ArrayList;
import java.util.List;
/**
* 书架的展示页面
*/
public class BookShelfFragment extends BaseFragment implements View.OnClickListener {
public static BookShelfFragment fragment;
private RelativeLayout rl_shelf;
private RelativeLayout rl_book_top;
private TextView tv_book;
private ImageView iv_search;
private TextView tv_exit;
private ImageView iv_shelf_line;
private GridView gv_shelf;
private RelativeLayout Rl_book_bottom;
private TextView tv_book_select;
private TextView tv_book_delete;
@Override
protected View initView() {
View view=View.inflate(context, R.layout.book_shelf_fragment,null);
rl_shelf = view.findViewById(R.id.rl_shelf);
rl_book_top = view.findViewById(R.id.rl_book_top);
tv_book = view.findViewById(R.id.tv_book);
iv_search = view.findViewById(R.id.iv_search);
iv_search.setOnClickListener(this);
tv_exit = view.findViewById(R.id.tv_exit);
tv_exit.setOnClickListener(this);
iv_shelf_line = view.findViewById(R.id.iv_shelf_line);
gv_shelf = view.findViewById(R.id.gv_shelf);
Rl_book_bottom = view.findViewById(R.id.Rl_book_bottom);
tv_book_select = view.findViewById(R.id.tv_book_select);
tv_book_select.setOnClickListener(this);
tv_book_delete = view.findViewById(R.id.tv_book_delete);
tv_book_delete.setOnClickListener(this);
fragment=this;
return view;
}
/**
* 重新设置尺寸
*/
private void setView(){
SetUiSize.setMarginTopRelative(rl_book_top,10);
SetUiSize.setTextViewSize(tv_book,20);
SetUiSize.setMarginLeftRelative(tv_book,10);
SetUiSize.setMarginVerticalRelative(tv_book,10);
SetUiSize.setWidthRelative(iv_search,18);
SetUiSize.setHeightRelative(iv_search,18);
SetUiSize.setMarginRightRelative(iv_search,35);
SetUiSize.setTextViewSize(tv_exit,20);
SetUiSize.setMarginRightRelative(tv_exit,35);
SetUiSize.setHeightLinear(iv_shelf_line,1);
SetUiSize.setMarginTopLinear(gv_shelf,15);
SetUiSize.setTextViewSize(tv_book_select,20);
SetUiSize.setMarginLeftRelative(tv_book_select,15);
SetUiSize.setMarginVerticalRelative(tv_book_select,15);
SetUiSize.setTextViewSize(tv_book_delete,20);
SetUiSize.setMarginRightRelative(tv_book_delete,15);
rl_shelf.setVisibility(View.VISIBLE);
}
@Override
protected void initData() {
super.initData();
setView();
query();
}
@SuppressLint("NonConstantResourceId")
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.iv_search://搜索
startActivity(new Intent(getActivity(), SearchActivity.class));
break;
case R.id.tv_exit://退出管理
handler.sendEmptyMessage(1);//刷新书架,取消选择
break;
case R.id.tv_book_select://全选和取消全选
isCheck();
break;
case R.id.tv_book_delete://从书架中删除小说
delete();
break;
}
}
/**
* 判断是否选中
*/
private void isCheck() {
boolean flag;
if (count()){
flag=true;
tv_book_select.setText("取消全选");
}else {
flag=false;
tv_book_select.setText("全选");
}
for (int i = 0; i < list.size(); i++) {
list.get(i).select=flag;
}
adapter.notifyDataSetChanged();
}
private List<Title> list=new ArrayList<>();
private ShelfAdapter adapter=new ShelfAdapter();
public class ShelfAdapter extends BaseAdapter{
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder=null;
if (convertView==null){
convertView=View.inflate(getActivity(),R.layout.grid_item_shelf,null);
holder=new Holder();
holder.iv_grid = convertView.findViewById(R.id.iv_grid);
SetUiSize.setWidthRelative(holder.iv_grid,90);
SetUiSize.setHeightRelative(holder.iv_grid,125);
holder.ll_content = convertView.findViewById(R.id.ll_content);
SetUiSize.setWidthRelative(holder.ll_content,100);
holder.tv_grid = convertView.findViewById(R.id.tv_grid);
SetUiSize.setTextViewSize(holder.tv_grid,15);
SetUiSize.setMarginTopLinear(holder.tv_grid,5);
holder.iv_select = convertView.findViewById(R.id.iv_select);
SetUiSize.setWidthRelative(holder.iv_select,25);
SetUiSize.setHeightRelative(holder.iv_select,25);
SetUiSize.setMarginRightRelative(holder.iv_select,5);
SetUiSize.setMarginBottomRelative(holder.iv_select,5);
convertView.setTag(holder);
}else {
holder= (Holder) convertView.getTag();
}
Title title = list.get(position);
getBitmapFromSd(position);
holder.iv_grid.setImageBitmap(title.bitmap);
holder.tv_grid.setText(title.name);
if (MainActivity.activity.exit){
if (title.select){
holder.iv_select.setBackgroundResource(R.drawable.checkbox_ic_selected);
}else {
holder.iv_select.setBackgroundResource(R.drawable.checkbox_ic_default);
}
holder.iv_select.setVisibility(View.VISIBLE);
}else {
holder.iv_select.setVisibility(View.GONE);
}
return convertView;
}
private class Holder{
public ImageView iv_grid;
public TextView tv_grid;
public ImageView iv_select;
public LinearLayout ll_content;
}
}
/**
* 查询书架数据
*/
@SuppressLint("Range")
private void query(){
list.clear();
DBHelper dbHelper=new DBHelper(getActivity(),1);
SQLiteDatabase database = dbHelper.getReadableDatabase();
String sql="CREATE TABLE IF NOT EXISTS shelf(\n" +
"\tbook VARCHAR(20) NOT NULL,\n" +
"\tauthor VARCHAR(30) NOT NULL,\n" +
"\tintroduce VARCHAR(200),\n" +
"\tpage VARCHAR(100),\n" +
"\torigin VARCHAR(100) NOT NULL,\n" +
"\tprogress INTEGER NOT NULL\n" +
");";
database.execSQL(sql);
Cursor cursor = database.query("shelf", null, null,
null, null, null, null);
Title title;
while (cursor.moveToNext()){
title = new Title();
title.iv_back=R.drawable.empty;
title.name=cursor.getString(cursor.getColumnIndex("book"));//书名
title.author=cursor.getString(cursor.getColumnIndex("author"));//作者
title.path=cursor.getString(cursor.getColumnIndex("origin"));
title.index=cursor.getInt(cursor.getColumnIndex("progress"));
title.imageName=cursor.getString(cursor.getColumnIndex("page"));
list.add(title);
}
cursor.close();
database.close();
gv_shelf.setAdapter(adapter);
gv_shelf.setOnItemClickListener((parent, view, position, id) -> {
if (MainActivity.activity.exit){
list.get(position).select=!list.get(position).select;
count();
adapter.notifyDataSetChanged();
}else {
Intent intent=new Intent(getActivity(), ReadActivity.class);
intent.putExtra("url",list.get(position).path);//章节页面
intent.putExtra("name",list.get(position).name);//书名
intent.putExtra("author",list.get(position).author);//作者
intent.putExtra("code","1");//表示是书架来源
intent.putExtra("page",list.get(position).index+"");//表示是阅读进度
startActivity(intent);
}
});
gv_shelf.setOnItemLongClickListener((parent, view, position, id) -> {
if (!MainActivity.activity.exit){//表示没有选中状态
MainActivity.activity.exit=true;//设置为选中状态
list.get(position).select=true;
iv_search.setVisibility(View.GONE);//隐藏搜索
tv_exit.setVisibility(View.VISIBLE);//显示退出管理
MainActivity.activity.rg_main.setVisibility(View.GONE);//隐藏底部导航按钮
Rl_book_bottom.setVisibility(View.VISIBLE);//显示底部按钮
count();
adapter.notifyDataSetChanged();//刷新视图
return true;
}
return false;
});
}
@SuppressLint("HandlerLeak")
public Handler handler=new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
switch (msg.what){
case 0://刷新书架
{
query();
}
break;
case 1://刷新书架,取消选择
{
refresh();
}
break;
case 2://删除书架
{
refresh();
query();
}
break;
}
}
};
//刷新书架,取消选择
private void refresh() {
if (list.size()>0){
int i = 0;
for (; i < list.size(); i++) {
list.get(i).select=false;
}
}
MainActivity.activity.exit=false;
tv_exit.setVisibility(View.GONE);//隐藏退出管理
iv_search.setVisibility(View.VISIBLE);//显示搜索
Rl_book_bottom.setVisibility(View.GONE);//隐藏底部按钮
MainActivity.activity.rg_main.setVisibility(View.VISIBLE);//显示底部导航按钮
adapter.notifyDataSetChanged();//刷新视图
}
private void getBitmapFromSd(int position) {
// /storage/sdcard/Android/data/packageName/files/
String filesPath = getActivity().getExternalFilesDir(null).getAbsolutePath();
String filePath = filesPath+"/"+list.get(position).imageName;
list.get(position).bitmap=BitmapFactory.decodeFile(filePath);
}
/**
* 统计判断是否修改选择按钮展示文字
*/
private boolean count(){
int i = 0;
int flag=0;
for (; i < list.size(); i++) {
if (list.get(i).select){
flag++;
}
}
if (flag<list.size()){
tv_book_select.setText("全选");
return true;
}else if (flag==list.size()){
tv_book_select.setText("取消全选");
}
return false;
}
/**
* 移除小说,并重新加载暑假数据
*/
private void delete(){
DBHelper dbHelper=new DBHelper(getActivity(),1);
SQLiteDatabase database = dbHelper.getReadableDatabase();
String sql="CREATE TABLE IF NOT EXISTS shelf(\n" +
"\tbook VARCHAR(20) NOT NULL,\n" +
"\tauthor VARCHAR(30) NOT NULL,\n" +
"\tintroduce VARCHAR(200),\n" +
"\tpage VARCHAR(100),\n" +
"\torigin VARCHAR(100) NOT NULL,\n" +
"\tprogress INTEGER NOT NULL\n" +
");";
database.execSQL(sql);
int i = 0;
for (; i < list.size(); i++) {
if (list.get(i).select){
database.delete("shelf","book = ? AND author = ?",
new String[]{list.get(i).name,list.get(i).author});
}
}
database.close();
//本地保存的图片不删除,用于后面优化复用图片
handler.sendEmptyMessage(2);
}
}
3、效果演示
3.1、书架效果
下图是正常情况下书架效果。
下图是长按后将小说从书架移除的效果。
3.2、历史阅读记录效果