安卓小項目【小說閱讀器】

來源:互聯網
上載者:User

標籤:

1,布局設定,LiearLayout 上中下三部分,其中小說主題內容部分為自訂view,比例是1:8:1

2,建立資料庫表  兩張表txt表和page表,兩張表進行主外部索引鍵關聯

public class DBHelper extends SQLiteOpenHelper {    public DBHelper(Context context) {        super(context, "read.db", null, 1);    }    public DBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {        super(context, name, factory, version);    }    @Override    public void onCreate(SQLiteDatabase db) {        db.execSQL("create table txt(id Integer primry key,full_path text,now_page integer,over_flag integer)");        db.execSQL("create table page(id integer primary key,txt_id integer,page_num integer,content text)");    }    @Override    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {    }}文本表
<span style="font-size:12px;">public class TxtDB {    public static void insertData(String fullPath) {        String sql = "select id from txt where full_path=?";        Cursor c = Globals.helper.getReadableDatabase().rawQuery(sql, new String[]{fullPath});        if (!c.moveToFirst()) {//如果不存在資料則插入資料            sql = "insert into txt(id,full_path,now_page,over_flag) values(?,?,?,?)";            Globals.helper.getWritableDatabase().execSQL(sql, new Object[]{1,fullPath,1,0});        }        c.close();    }    public static Map<String, Object> loadData(String fullPath) {        Map<String, Object> map = new HashMap<>();        String sql = "select id,now_page,over_flag from txt where full_path=?";        Cursor c = Globals.helper.getReadableDatabase().rawQuery(sql, new String[]{fullPath});        while (c.moveToNext()) {            map.put("txtId", c.getInt(0));            map.put("nowPage", c.getInt(1));            map.put("overFlag", c.getInt(2));        }        c.close();        return map;    }    public static void updateOverFlag(String fullPath) {        String sql = "update txt set over_flag=1 where full_path=?";        Globals.helper.getWritableDatabase().execSQL(sql, new Object[]{fullPath});    }}</span>
分頁表
<span style="font-size:12px;">public class PageDB {    private static int pageNum;    public static void insertDate(Map<String, Object> map) {        String sql = "insert into page(txt_id,page_num,content) values(?,?,?)";        Globals.helper.getWritableDatabase().execSQL(sql, new Object[]{map.get("txtId"), map.get("pageNum"), map.get("content")});    }    public static String findContent(int txtId, int pageNum) {        String content = null;        String sql = "select content from page where txt_id=? and page_num=?";        Cursor c = Globals.helper.getReadableDatabase().rawQuery(sql, new String[]{txtId + "", pageNum + ""});        while (c.moveToNext()) {            content = c.getString(0);        }        c.close();        return content;    }    public static int findPageNum(int txtId){        String sql="select count(*) from page where txt_id=?";        Cursor c= Globals.helper.getReadableDatabase().rawQuery(sql,new String[]{txtId+""});        while(c.moveToNext()){            pageNum=c.getInt(0);        }        c.close();        return pageNum;    }}</span>

3,定義一個全域可以使用的類Globals ,在裡面設定頁面內容,每行顯示的字數,字間距,行間距,頁面邊界,獲得安卓裝置的螢幕寬度和高度

public class Globals {    public static int  SCREEN_WIDTH;    public static int  SCREEN_HEIGHT;    public static  int LINE_CHAR_COUNT=20;//每行顯示20個字    public static  int CHAR_SEP=2;//字間距    public static  int PAGE_SEP=5;//頁面邊界    public static int LINE_SEP=2;//行間距    public static  int CHAR_SIZE;//字元大小,需計算,保證能根據螢幕大小自適應    public static int LINE_COUNT;//每頁顯示的行數,需計算。 public static  void init(Activity a){        SCREEN_WIDTH=a.getWindowManager().getDefaultDisplay().getWidth();//獲得螢幕寬度        SCREEN_HEIGHT=a.getWindowManager().getDefaultDisplay().getHeight();//獲得螢幕高度        CHAR_SIZE=(SCREEN_WIDTH-PAGE_SEP*2-(LINE_CHAR_COUNT-1)*CHAR_SEP)/LINE_CHAR_COUNT;//計算出字元大小        LINE_COUNT=SCREEN_HEIGHT*4/5/(CHAR_SIZE+LINE_SEP);//計算每頁顯示的行數,並跟布局相適應,占螢幕的五分之四    }}4,自訂MyView,滑動翻頁<pre name="code" class="java">public class MyView extends View {    private String content;    private MainActivity a;    private float startX;    private float nowX;    private String preContent;//準備上一頁和下一頁的內容    private String nextContent;    public MyView(Context context) {        super(context);    }    public MyView(Context context, AttributeSet attrs) {        super(context, attrs);        a = (MainActivity) context;        this.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {            }        });        this.setOnTouchListener(new OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                if (event.getAction() == MotionEvent.ACTION_DOWN) {                    startX = event.getX();                } else if (event.getAction() == MotionEvent.ACTION_MOVE) {                    nowX = event.getX();                    postInvalidate();//重新調用onDraw方法                } else if (event.getAction() == MotionEvent.ACTION_UP) {                    if (Math.abs(nowX - startX) >= 50) {//nowX和startX的絕對值大於50 的話才執行翻頁                        if (nowX > startX) {//上一頁                            if (a.getNowPageNum() > 1) {                                a.setNowPageNum(a.getNowPageNum() - 1);//翻到上一頁                                changeData();                            }                        }                        if (nowX < startX) {//下一頁                            if (a.getNowPageNum() < a.getPageNum()) {                                a.setNowPageNum(a.getNowPageNum() + 1);//翻到下一頁                                changeData();                            }                        }                    }                    startX = 0;                    nowX = 0;                }                return false;            }        });    }    public MyView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);    }    public void changeData() {        content = PageDB.findContent((int) a.getTxtMap().get("txtId"),a.getNowPageNum());        if (a.getNowPageNum() > 1) {//當前頁不是第一頁的時候            preContent = PageDB.findContent((int) a.getTxtMap().get("txtId"), a.getNowPageNum() - 1);        } else {            preContent = null;        }        if (a.getNowPageNum() < a.getPageNum()) {//當前頁不是最後一頁            nextContent = PageDB.findContent((int) a.getTxtMap().get("txtId"),a.getNowPageNum()+ 1);        } else {            nextContent = null;        }        a.getHandler().sendEmptyMessage(1);        super.postInvalidate();//調用OnDraw方法;    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        if (content != null) {            String[] allValues = content.split(Globals.END_FLAG);            for (int i = 0; i < allValues.length; i++) {                for (int j = 0; j < allValues[i].length(); j++) {                    if (j + i * Globals.char_line_conut < content.length()) {                        Paint paint = new Paint();                        paint.setColor(Color.BLACK);                        paint.setTextSize(Globals.char_size);                        canvas.drawText(String.valueOf(allValues[i].charAt(j)),                                Globals.page_sep + j * (Globals.char_size + Globals.char_sep) + (nowX-startX),                                i * (Globals.char_size + Globals.line_sep), paint);                    }                }            }        }        if (nowX > startX && preContent != null) {            String[] allValues = preContent.split(Globals.END_FLAG);            for (int i = 0; i < allValues.length; i++) {                for (int j = 0; j < allValues[i].length(); j++) {                    if (j + i * Globals.char_line_conut < content.length()) {                        Paint paint = new Paint();                        paint.setColor(Color.BLACK);                        paint.setTextSize(Globals.char_size);                        canvas.drawText(String.valueOf(allValues[i].charAt(j)),                                Globals.page_sep + j * (Globals.char_size + Globals.char_sep) +(nowX-startX) -Globals.screen_width,                                i * (Globals.char_size + Globals.line_sep), paint);                    }                }            }        }        if (nowX < startX && nextContent != null) {            String[] allValues = nextContent.split(Globals.END_FLAG);            for (int i = 0; i < allValues.length; i++) {                for (int j = 0; j < allValues[i].length(); j++) {                    if (j + i * Globals.char_line_conut < content.length()) {                        Paint paint = new Paint();                        paint.setColor(Color.BLACK);                        paint.setTextSize(Globals.char_size);                        canvas.drawText(String.valueOf(allValues[i].charAt(j)),                                Globals.page_sep + j * (Globals.char_size + Globals.char_sep) +(nowX-startX) +Globals.screen_width,                                i * (Globals.char_size + Globals.line_sep), paint);                    }                }            }        }    }}

 

5,將文本存放在sdcard的根目錄,以西遊記作為示範,獲得文本的絕對路徑,用字元流進行按行讀取

<pre name="code" class="java">public class MainActivity extends AppCompatActivity {    static MyView contentView;    static TextView pageView;    private Map<String, Object> txtMap;    private Map<String, Object> pageMap = new HashMap<>();    private StringBuffer sb = new StringBuffer();    private int lineCount = 0;//每頁的行數    static int pageNum = 1;//總頁數    static int nowPageNum = 1;//當前頁數    private String fullPath;    static Handler handler = new Handler() {        @Override        public void handleMessage(Message msg) {            if (msg.what == 0) {                pageView.setText("正在分頁,已經分解:" + pageNum);            } else if (msg.what == 1) {                pageView.setText("分頁已經完成" + nowPageNum + "/" + pageNum);            }        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        Globals.init(this);        setContentView(R.layout.activity_main);        contentView = (MyView) findViewById(R.id.content_view);        pageView = (TextView) findViewById(R.id.page_view);        fullPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/xiyouji.txt";//擷取檔案路徑        TxtDB.insertIntoTxt(fullPath);        txtMap = TxtDB.loadTxtByFullpath(fullPath);        if ((int) txtMap.get("overFlag") == 0) {            //還未進行分頁            new Thread() {                @Override                public void run() {                    try {                        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(fullPath), "GBK"));                        String line = null;                        while ((line = br.readLine()) != null) {                            while (line.length() > Globals.char_line_conut) {                                String str = line.substring(0, Globals.char_line_conut);                                line = line.substring(Globals.char_line_conut);                                addLine(str);                            }                            addLine(line);//行餘下的不足以湊成一行的字數添加成一行                        }                        br.close();                        handler.sendEmptyMessage(1);                        TxtDB.updateOverFlag(fullPath);                    } catch (Exception e) {                        e.printStackTrace();                    }                }            }.start();        } else {            //已經分頁完成            pageNum = PageDB.getPageCount((int) txtMap.get("txtId"));            nowPageNum = (int) txtMap.get("nowPage");            contentView.changeData();        }    }    @Override    protected void onDestroy() {        TxtDB.updateNowPaga((int) txtMap.get("nowPage"), fullPath);        super.onDestroy();    }    public void addLine(String str) {//行湊成頁之後存放到資料庫中        sb.append(str);        sb.append(Globals.END_FLAG);        lineCount++;        if (lineCount == Globals.line_count) {            pageMap.put("txtid", txtMap.get("txtId"));            pageMap.put("pagenum", pageNum++);            pageMap.put("content", sb.toString());            PageDB.insertIntoPageDB(pageMap);            if (pageNum == 10) {                contentView.changeData();            }            handler.sendEmptyMessage(0);            sb = new StringBuffer();            lineCount = 0;//再次初始化供下次迴圈使用        }    }    public Map<String, Object> getTxtMap() {        return txtMap;    }    public void setTxtMap(Map<String, Object> txtMap) {        this.txtMap = txtMap;    }    public int getPageNum() {        return pageNum;    }    public void setPageNum(int pageNum) {        this.pageNum = pageNum;    }    public int getNowPageNum() {        return nowPageNum;    }    public void setNowPageNum(int nowPageNum) {        this.nowPageNum = nowPageNum;    }    public Handler getHandler() {        return handler;    }    public void setHandler(Handler handler) {        this.handler = handler;    }    public Map<String, Object> getPageMap() {        return pageMap;    }}






安卓小項目【小說閱讀器】

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.