小说阅读软件书架界面和历史记录界面

1、引言

终于修改到书架界面和历史阅读记录界面了,修改完这两个界面就算完成一大半了,这两个界面其实都差不多,代码逻辑都一样,因此后面也会只展示书架界面的代码,历史阅读记录界面就展示效果图就行了。

2、实现代码

2.1、书架界面主布局

java 复制代码
<?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、书架界面实际布局

java 复制代码
<?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、逻辑代码

在这里其实还要配合上次阅读界面那里添加书架和历史记录查看,但上次那里没修改,不过没太大变化,可以参考上次阅读界面那里。

java 复制代码
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、历史阅读记录效果

相关推荐
后端码匠3 小时前
MySQL 8.0安装(压缩包方式)
android·mysql·adb
梓仁沐白4 小时前
Android清单文件
android
董可伦7 小时前
Dinky 安装部署并配置提交 Flink Yarn 任务
android·adb·flink
每次的天空7 小时前
Android学习总结之Glide自定义三级缓存(面试篇)
android·学习·glide
恋猫de小郭8 小时前
如何查看项目是否支持最新 Android 16K Page Size 一文汇总
android·开发语言·javascript·kotlin
flying robot9 小时前
小结:Android系统架构
android·系统架构
xiaogai_gai9 小时前
有效的聚水潭数据集成到MySQL案例
android·数据库·mysql
鹅鹅鹅呢10 小时前
mysql 登录报错:ERROR 1045(28000):Access denied for user ‘root‘@‘localhost‘ (using password Yes)
android·数据库·mysql
在人间负债^10 小时前
假装自己是个小白 ---- 重新认识MySQL
android·数据库·mysql
Unity官方开发者社区10 小时前
Android App View——团结引擎车机版实现安卓应用原生嵌入 3D 开发场景
android·3d·团结引擎1.5·团结引擎车机版