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

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、历史阅读记录效果

相关推荐
没有了遇见18 分钟前
Android 通过 SO 库安全存储敏感数据,解决接口劫持问题
android
hsx66619 分钟前
使用一个 RecyclerView 构建复杂多类型布局
android
hsx66621 分钟前
利用 onMeasure、onLayout、onDraw 创建自定义 View
android
守城小轩23 分钟前
Chromium 136 编译指南 - Android 篇:开发工具安装(三)
android·数据库·redis
whysqwhw1 小时前
OkHttp平台抽象机制分析
android
hsx6662 小时前
Android 内存泄漏避坑
android
whysqwhw2 小时前
OkHttp之okhttp-bom模块的分析
android
餐桌上的王子2 小时前
Android 构建可管理生命周期的应用(二)
android
幽你一默3 小时前
Android 版本差异速查表(开发者视角)
android
不萌3 小时前
android 项目中的屏幕适配方案
android