效果图:
代码:
PS:代码比较乱,暂不整理
BookPageFactory.java
/** * Author : hmg25 * Description : */ package com2.aiai.www; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.io.UnsupportedEncodingException; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Vector; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Align; public class BookPageFactory { private File book_file = null; private MappedByteBuffer m_mbBuf = null; private int m_mbBufLen = 0; private int m_mbBufBegin = 0; private int m_mbBufEnd = 0; private String m_strCharsetName = "UTF-8"; //"GBK"; private Bitmap m_book_bg = null; private int mWidth; private int mHeight; private Vector<String> m_lines = new Vector<String>(); public ArrayList m_pageBufferBegin = new ArrayList(); private int m_fontSize = 24; private int m_textColor = Color.BLACK; private int m_backColor = 0xffff9e85; //背景颜色 private int marginWidth = 15; // 左右与边缘距离 private int marginHeight = 20; // 上下与边缘距离 private int mLineCount; // 每页可以显示的行数 private float mVisibleHeight; // 绘制内容的宽 private float mVisibleWidth; // 绘制内容的高 private boolean m_isfirstPage,m_islastPage; // private int m_nLineSpaceing = 5; private int mPageCurrent=1; public int mPageTotal=1; private Paint mPaint; public BookPageFactory(int w, int h) { // TODO Auto-generated constructor stub mWidth = w; mHeight = h; mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setTextAlign(Align.LEFT); mPaint.setTextSize(m_fontSize); mPaint.setColor(m_textColor); mVisibleWidth = mWidth - marginWidth * 2; mVisibleHeight = mHeight - marginHeight * 2; mLineCount = (int) (mVisibleHeight / m_fontSize); //可显示的行数 } public void openbook(String strFilePath) throws IOException { book_file = new File(strFilePath); long lLen = book_file.length(); m_mbBufLen = (int) lLen; m_mbBuf = new RandomAccessFile(book_file, "r").getChannel().map( FileChannel.MapMode.READ_ONLY, 0, lLen); } protected byte[] readParagraphBack(int nFromPos) { int nEnd = nFromPos; int i; byte b0, b1; if (m_strCharsetName.equals("UTF-16LE")) { i = nEnd - 2; while (i > 0) { b0 = m_mbBuf.get(i); b1 = m_mbBuf.get(i + 1); if (b0 == 0x0a && b1 == 0x00 && i != nEnd - 2) { i += 2; break; } i--; } } else if (m_strCharsetName.equals("UTF-16BE")) { i = nEnd - 2; while (i > 0) { b0 = m_mbBuf.get(i); b1 = m_mbBuf.get(i + 1); if (b0 == 0x00 && b1 == 0x0a && i != nEnd - 2) { i += 2; break; } i--; } } else { i = nEnd - 1; while (i > 0) { b0 = m_mbBuf.get(i); if (b0 == 0x0a && i != nEnd - 1) { i++; break; } i--; } } if (i < 0) i = 0; int nParaSize = nEnd - i; int j; byte[] buf = new byte[nParaSize]; for (j = 0; j < nParaSize; j++) { buf[j] = m_mbBuf.get(i + j); } return buf; } // 读取上一段落 protected byte[] readParagraphForward(int nFromPos) { int nStart = nFromPos; int i = nStart; byte b0, b1; // 根据编码格式判断换行 if (m_strCharsetName.equals("UTF-16LE")) { while (i < m_mbBufLen - 1) { b0 = m_mbBuf.get(i++); b1 = m_mbBuf.get(i++); if (b0 == 0x0a && b1 == 0x00) { break; } } } else if (m_strCharsetName.equals("UTF-16BE")) { while (i < m_mbBufLen - 1) { b0 = m_mbBuf.get(i++); b1 = m_mbBuf.get(i++); if (b0 == 0x00 && b1 == 0x0a) { break; } } } else { while (i < m_mbBufLen) { b0 = m_mbBuf.get(i++); if (b0 == 0x0a) { break; } } } int nParaSize = i - nStart; byte[] buf = new byte[nParaSize]; for (i = 0; i < nParaSize; i++) { buf[i] = m_mbBuf.get(nFromPos + i); } return buf; } /* public void gotoNextPage() { if(mPageCurrent>mPageTotal) return ; mPageCurrent++; gotoPage(mPageCurrent); } public void gotoPrePage() { if(mPageCurrent<=1) return ; mPageCurrent--; gotoPage(mPageCurrent); }*/ //跳入指定页 public void gotoPage(int page) { String str; if(page <= m_pageBufferBegin.size() && page >=1) { str = m_pageBufferBegin.get(page-1).toString(); m_mbBufBegin = Integer.valueOf(str).intValue(); str = m_pageBufferBegin.get(page+1-1).toString(); m_mbBufEnd = Integer.valueOf(str).intValue(); mPageCurrent = page; try { prePage(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { nextPage(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("gotoPage m_mbBufBegin="+m_mbBufBegin+",m_mbBufEnd="+m_mbBufEnd+",mPageCurrent="+(mPageCurrent)); } } //获得总页数 public int getTotalPages() { String strParagraph = ""; Vector<String> lines = new Vector<String>(); int m_mbBuftmp = 0; int m_pages=1; m_pageBufferBegin.clear(); m_pageBufferBegin.add(0); while (/*lines.size() < mLineCount && */m_mbBuftmp < m_mbBufLen) { byte[] paraBuf = readParagraphForward(m_mbBuftmp); // 读取一个段落 m_mbBuftmp += paraBuf.length; try { strParagraph = new String(paraBuf, m_strCharsetName); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } String strReturn = ""; if (strParagraph.indexOf("\r\n") != -1) { strReturn = "\r\n"; strParagraph = strParagraph.replaceAll("\r\n", ""); } else if (strParagraph.indexOf("\n") != -1) { strReturn = "\n"; strParagraph = strParagraph.replaceAll("\n", ""); } if (strParagraph.length() == 0) { lines.add(strParagraph); } while (strParagraph.length() > 0) { int nSize = mPaint.breakText(strParagraph, true, mVisibleWidth, null); lines.add(strParagraph.substring(0, nSize)); strParagraph = strParagraph.substring(nSize); if (lines.size() >= mLineCount) { break; } } if (strParagraph.length() != 0) { try { m_mbBuftmp -= (strParagraph + strReturn) .getBytes(m_strCharsetName).length; } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(lines.size() >= mLineCount) { m_pages++; m_pageBufferBegin.add(m_mbBuftmp); lines.clear(); } } return m_pages; //(lines.size()/mLineCount+1); } protected Vector<String> pageDown() { String strParagraph = ""; Vector<String> lines = new Vector<String>(); while (lines.size() < mLineCount && m_mbBufEnd < m_mbBufLen) { byte[] paraBuf = readParagraphForward(m_mbBufEnd); // 读取一个段落 m_mbBufEnd += paraBuf.length; //System.out.println("paraBuf.length="+paraBuf.length); //System.out.println("pageDown() 1 m_mbBufEnd"+m_mbBufEnd); try { strParagraph = new String(paraBuf, m_strCharsetName); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } String strReturn = ""; if (strParagraph.indexOf("\r\n") != -1) { strReturn = "\r\n"; strParagraph = strParagraph.replaceAll("\r\n", ""); } else if (strParagraph.indexOf("\n") != -1) { strReturn = "\n"; strParagraph = strParagraph.replaceAll("\n", ""); } if (strParagraph.length() == 0) { lines.add(strParagraph); } while (strParagraph.length() > 0) { int nSize = mPaint.breakText(strParagraph, true, mVisibleWidth, null); lines.add(strParagraph.substring(0, nSize)); strParagraph = strParagraph.substring(nSize); if (lines.size() >= mLineCount) { break; } } if (strParagraph.length() != 0) { try { m_mbBufEnd -= (strParagraph + strReturn) .getBytes(m_strCharsetName).length; //System.out.println("pageDown() 2 m_mbBufEnd"+m_mbBufEnd); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } //System.out.println("pageDown() lines"+lines); System.out.println("current m_mbBufBegin="+m_mbBufBegin+",m_mbBufEnd="+m_mbBufEnd+",mPageCurrent="+(mPageCurrent)); return lines; } protected void pageUp() { if (m_mbBufBegin < 0) m_mbBufBegin = 0; Vector<String> lines = new Vector<String>(); String strParagraph = ""; while (lines.size() < mLineCount && m_mbBufBegin > 0) { Vector<String> paraLines = new Vector<String>(); byte[] paraBuf = readParagraphBack(m_mbBufBegin); m_mbBufBegin -= paraBuf.length; try { strParagraph = new String(paraBuf, m_strCharsetName); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } strParagraph = strParagraph.replaceAll("\r\n", ""); strParagraph = strParagraph.replaceAll("\n", ""); if (strParagraph.length() == 0) { paraLines.add(strParagraph); } while (strParagraph.length() > 0) { int nSize = mPaint.breakText(strParagraph, true, mVisibleWidth, null); paraLines.add(strParagraph.substring(0, nSize)); strParagraph = strParagraph.substring(nSize); } lines.addAll(0, paraLines); } while (lines.size() > mLineCount) { try { m_mbBufBegin += lines.get(0).getBytes(m_strCharsetName).length; lines.remove(0); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } } m_mbBufEnd = m_mbBufBegin; //System.out.println("pageUp() m_mbBufEnd"+m_mbBufEnd); return; } protected void prePage() throws IOException { System.out.println("m_mbBufBegin="+m_mbBufBegin); if (m_mbBufBegin <=0) { m_mbBufBegin = 0; m_isfirstPage=true; return; }else m_isfirstPage=false; m_lines.clear(); mPageCurrent--; pageUp(); m_lines = pageDown(); } public void nextPage() throws IOException { if (m_mbBufEnd >= m_mbBufLen) { m_islastPage=true; return; }else m_islastPage=false; m_lines.clear(); mPageCurrent++; m_mbBufBegin = m_mbBufEnd; m_lines = pageDown(); } public void onDraw(Canvas c) { if (m_lines.size() == 0) m_lines = pageDown(); if (m_lines.size() > 0) { if (m_book_bg == null) c.drawColor(m_backColor); else c.drawBitmap(m_book_bg, 0, 0, null); int y = marginHeight; for (String strLine : m_lines) { y += m_fontSize; c.drawText(strLine, marginWidth, y, mPaint); } } float fPercent = (float) (m_mbBufBegin * 1.0 / m_mbBufLen); //System.out.println("m_mbBufBegin="+m_mbBufBegin+",m_mbBufLen="+m_mbBufLen); //System.out.println("fPercent="+fPercent); DecimalFormat df = new DecimalFormat("#0.0"); String strPercent = df.format(fPercent * 100) + "%"; int nPercentWidth = (int) mPaint.measureText("999.9%") + 1; String strLineCurrent=mPageCurrent+"/"+mPageTotal; //c.drawText(strPercent, mWidth - nPercentWidth, mHeight - 5, mPaint); c.drawText(strLineCurrent, mWidth - nPercentWidth, mHeight - 5, mPaint); } public void setBgBitmap(Bitmap BG) { m_book_bg = BG; } public boolean isfirstPage() { return m_isfirstPage; } public boolean islastPage() { return m_islastPage; } }
ChapterIndex.java
package com2.aiai.www; import com2.aiai.www.R; import android.app.Activity; import android.app.Dialog; import android.app.ProgressDialog; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.AdapterView.OnItemClickListener; public class ChapterIndex extends Activity { private ListView listView; private ReadChapter mReadChapter = new ReadChapter(); private static ProgressDialog pd; public static boolean pdflag=false; public static int chapterIndex=0; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); String[]strs1={ "第一回 西门庆热结十弟兄 武二郎冷遇亲哥嫂", "第二回 俏潘娘帘下勾情 老王婆茶坊说技", "第三回 定挨光王婆受贿 设圈套浪子私挑", "第四回 赴巫山潘氏幽欢 闹茶坊郓哥义愤", "第五回 捉奸情郓哥定计 饮鸩药武大遭殃", "第六回 何九受贿瞒天 王婆帮闲遇雨", "第七回 薛媒婆说娶孟三儿 杨姑娘气骂张四舅", "第八回 盼情郎佳人占鬼卦 烧夫灵和尚听淫声", "第九回 西门庆偷娶潘金莲 武都头误打李皂隶", "第十回 义士充配孟州道 妻妾玩赏芙蓉亭"}; String[]strs2={ "第十一回 潘金莲激打孙雪娥 西门庆梳笼李桂姐", "第十二回 潘金莲私仆受辱 刘理星魇胜求财", "第十三回 李瓶姐墙头密约 迎春儿隙底私窥", "第十四回 花子虚因气丧身 李瓶儿迎奸赴会", "第十五回 佳人笑赏玩灯楼 狎客帮嫖丽春院", "第十六回 西门庆择吉佳期 应伯爵追欢喜庆", "第十七回 宇给事劾倒杨提督 李瓶儿许嫁蒋竹山", "第十八回 赂相府西门脱祸 见娇娘敬济销魂", "第十九回 草里蛇逻打蒋竹山 李瓶儿情感西门庆", "第二十回 傻帮闲趋奉闹华筵 痴子弟争锋毁花院"}; String[]strs3={ "第二十一回 吴月娘扫雪烹茶 应伯爵替花邀酒", "第二十二回 蕙莲儿偷期蒙爱 春梅姐正色闲邪", "第二十三回 赌棋枰瓶儿输钞 觑藏春潘氏潜踪", "第二十四回 敬济元夜戏娇姿 惠祥怒詈来旺妇", "第二十五回 吴月娘春昼秋千 来旺儿醉中谤仙", "第二十六回 来旺儿递解徐州 宋蕙莲含羞自缢", "第二十七回 李瓶儿私语翡翠轩 潘金莲醉闹葡萄架", "第二十八回 陈敬济徼幸得金莲 西门庆糊涂打铁棍", "第二十九回 吴神仙冰鉴定终身 潘金莲兰汤邀午战", "第三十回 蔡太师擅恩锡爵 西门庆生子加官"}; String[]strs4={ "第三十一回 琴童儿藏壶构衅 西门庆开宴为欢", "第三十二回 李桂姐趋炎认女 潘金莲怀妒惊儿", "第三十三回 陈敬济失钥罚唱 韩道国纵妇争锋", "第三十四回 献芳樽内室乞恩 受私贿后庭说事", "第三十五回 西门庆为男宠报仇 书童儿作女妆媚客", "第三十六回 翟管家寄书寻女子 蔡状元留饮借盘缠", "第三十七回 冯妈妈说嫁韩爱姐 西门庆包占王六儿", "第三十八回 王六儿棒槌打捣鬼 潘金莲雪夜弄琵琶", "第三十九回 寄法名官哥穿道服 散生日敬济拜冤家", "第四十回 抱孩童瓶儿希宠 妆丫鬟金莲市爱"}; String[]strs5={ "第四十一回 两孩儿联姻共笑嬉 二佳人愤深同气苦", "第四十二回 逞豪华门前放烟火 赏元宵楼上醉花灯", "第四十三回 争宠爱金莲惹气 卖富贵吴月攀亲", "第四十四回 避马房侍女偷金 下象棋佳人消夜", "第四十五回 应伯爵劝当铜锣 李瓶儿解衣银姐", "第四十六回 元夜游行遇雪雨 妻妾戏笑卜龟儿", "第四十七回 苗青贪财害主 西门枉法受贿", "第四十八回 弄私情戏赠一枝桃 走捷径探归七件事", "第四十九回 请巡按屈体求荣 遇胡僧现身施药", "第五十回 琴童潜听燕莺欢 玳安嬉游蝴蝶巷"}; String[]strs6={ "第五十一回 打猫儿金莲品玉 斗叶子敬济输金", "第五十二回 应伯爵山洞戏春娇 潘金莲花园调爱婿", "第五十三回 潘金莲惊散幽欢 吴月娘拜求子息", "第五十四回 应伯爵隔花戏金钏 任医官垂帐诊瓶儿", "第五十五回 西门庆两番庆寿旦 苗员外一诺送歌童", "第五十六回 西门庆捐金助朋友 常峙节得钞傲妻儿", "第五十七回 开缘簿千金喜舍 戏雕栏一笑回嗔", "第五十八回 潘金莲打狗伤人 孟玉楼周贫磨镜", "第五十九回 西门庆露阳惊爱月 李瓶儿睹物哭官哥", "第六十回 李瓶儿病缠死孽 西门庆官作生涯"}; String[]strs7={ "第六十一回 西门庆乘醉烧阴户 李瓶儿带病宴重阳", "第六十二回 潘道士法遣黄巾士 西门庆大哭李瓶儿", "第六十三回 韩画士传真作遗爱 西门庆观戏动深悲", "第六十四回 玉箫跪受三章约 书童私挂一帆风", "第六十五回 愿同穴一时丧礼盛 守孤灵半夜口脂香", "第六十六回 翟管家寄书致赙 黄真人发牒荐亡", "第六十七回 西门庆书房赏雪 李瓶儿梦诉幽情", "第六十八回 应伯爵戏衔玉臂 玳安儿密访蜂媒", "第六十九回 招宣府初调林太太 丽春院惊走王三官", "第七十回 老太监引酌朝房 二提刑庭参太尉"}; String[]strs8={ "第七十一回 李瓶儿何家托梦 提刑官引奏朝仪", "第七十二回 潘金莲抠打如意儿 王三官义拜西门庆", "第七十三回 潘金莲不愤忆吹箫 西门庆新试白绫带", "第七十四回 潘金莲香腮偎玉 薛姑子佛口谈经", "第七十五回 因抱恙玉姐含酸 为护短金莲泼醋", "第七十六回 春梅娇撒西门庆 画童哭躲温葵轩", "第七十七回 西门庆踏雪访爱月 贲四嫂带水战情郎", "第七十八回 林太太鸳帏再战 如意儿茎露独尝", "第七十九回 西门庆贪欲丧命 吴月娘失偶生儿", "第八十回 潘金莲售色赴东床 李娇儿盗财归丽院"}; String[]strs9={ "第八十一回 韩道国拐财远遁 汤来保欺主背恩", "第八十二回 陈敬济弄一得双 潘金莲热心冷面", "第八十三回 秋菊含恨泄幽情 春梅寄柬谐佳会", "第八十四回 吴月娘大闹碧霞宫 曾静师化缘雪涧洞", "第八十五回 吴月娘识破奸情 春梅姐不垂别泪", "第八十六回 雪娥唆打陈敬济 金莲解渴王潮儿", "第八十七回 王婆子贪财忘祸 武都头杀嫂祭兄", "第八十八回 陈敬济感旧祭金莲 庞大姐埋尸托张胜", "第八十九回 清明节寡妇上新坟 永福寺夫人逢故主", "第九十回 来旺偷拐孙雪娥 雪娥受辱守备府"}; String[]strs10={ "第九十一回 孟玉楼爱嫁李衙内 李衙内怒打玉簪儿", "第九十二回 陈敬济被陷严州府 吴月娘大闹授官厅", "第九十三回 王杏庵义恤贫儿 金道士娈淫少弟", "第九十四回 大酒楼刘二撒泼 洒家店雪娥为娼", "第九十五回 玳安儿窃玉成婚 吴典恩负心被辱", "第九十六回 春梅姐游旧家池馆 杨光彦作当面豺狼", "第九十七回 假弟妹暗续鸾胶 真夫妇明谐花烛", "第九十八回 陈敬济临清逢旧识 韩爱姐翠馆遇情郎", "第九十九回 刘二醉骂王六儿 张胜窃听张敬济", "第一百回 韩爱姐路遇二捣鬼 普静师幻度孝哥儿"}; listView=new ListView(this); String[]strs = null; switch(chapterIndex) { case 0: strs = strs1; break; case 10: strs = strs2; break; case 20: strs = strs3; break; case 30: strs = strs4; break; case 40: strs = strs5; break; case 50: strs = strs6; break; case 60: strs = strs7; break; case 70: strs = strs8; break; case 80: strs = strs9; break; case 90: strs = strs10; break; default: strs = strs1; break; } listView.setAdapter(new ArrayAdapter<String>(this, R.layout.my_simple_list_item_2,strs)); listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub if(arg2<=9 && arg2>=0) { pdflag = true; pd = ProgressDialog.show(ChapterIndex.this, null, "正在进入,请稍候!"); ReadChapter.chapterNum=arg2+chapterIndex; System.out.println("###num="+ReadChapter.chapterNum); startActivity(new Intent(ChapterIndex.this, ReadChapter.class)); } } }); setContentView(listView); } @Override protected void onStop() { // TODO Auto-generated method stub if (pdflag) { if (pd.isShowing()) { pd.dismiss(); pdflag = false; } } super.onStop(); } }
PageWidget.java
package com2.aiai.www; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.ColorMatrix; import android.graphics.ColorMatrixColorFilter; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PointF; import android.graphics.Region; import android.graphics.drawable.GradientDrawable; import android.view.MotionEvent; import android.view.View; import android.widget.Scroller; public class PageWidget extends View { private static final String TAG = "hmg"; private int mWidth = 480; private int mHeight = 800; private int mCornerX = 0; // 拖拽点对应的页脚 private int mCornerY = 0; private Path mPath0; private Path mPath1; Bitmap mCurPageBitmap = null; // 当前页 Bitmap mNextPageBitmap = null; PointF mTouch = new PointF(); // 拖拽点 PointF mBezierStart1 = new PointF(); // 贝塞尔曲线起始点 PointF mBezierControl1 = new PointF(); // 贝塞尔曲线控制点 PointF mBeziervertex1 = new PointF(); // 贝塞尔曲线顶点 PointF mBezierEnd1 = new PointF(); // 贝塞尔曲线结束点 PointF mBezierStart2 = new PointF(); // 另一条贝塞尔曲线 PointF mBezierControl2 = new PointF(); PointF mBeziervertex2 = new PointF(); PointF mBezierEnd2 = new PointF(); float mMiddleX; float mMiddleY; float mDegrees; float mTouchToCornerDis; ColorMatrixColorFilter mColorMatrixFilter; Matrix mMatrix; float[] mMatrixArray = { 0, 0, 0, 0, 0, 0, 0, 0, 1.0f }; boolean mIsRTandLB; // 是否属于右上左下 float mMaxLength = (float) Math.hypot(mWidth, mHeight); int[] mBackShadowColors; int[] mFrontShadowColors; GradientDrawable mBackShadowDrawableLR; GradientDrawable mBackShadowDrawableRL; GradientDrawable mFolderShadowDrawableLR; GradientDrawable mFolderShadowDrawableRL; GradientDrawable mFrontShadowDrawableHBT; GradientDrawable mFrontShadowDrawableHTB; GradientDrawable mFrontShadowDrawableVLR; GradientDrawable mFrontShadowDrawableVRL; Paint mPaint; Scroller mScroller; public PageWidget(Context context) { super(context); // TODO Auto-generated constructor stub mPath0 = new Path(); mPath1 = new Path(); createDrawable(); mPaint = new Paint(); mPaint.setStyle(Paint.Style.FILL); ColorMatrix cm = new ColorMatrix(); float array[] = { 0.55f, 0, 0, 0, 80.0f, 0, 0.55f, 0, 0, 80.0f, 0, 0, 0.55f, 0, 80.0f, 0, 0, 0, 0.2f, 0 }; cm.set(array); mColorMatrixFilter = new ColorMatrixColorFilter(cm); mMatrix = new Matrix(); mScroller = new Scroller(getContext()); mTouch.x = 0.01f; // 不让x,y为0,否者在点计算时会有问题 mTouch.y = 0.01f; } /** * Author : hmg25 Version: 1.0 Description : 计算拖拽点对应的拖拽脚 */ public void calcCornerXY(float x, float y) { if (x <= mWidth / 2) mCornerX = 0; else mCornerX = mWidth; if (y <= mHeight / 2) mCornerY = 0; else mCornerY = mHeight; if ((mCornerX == 0 && mCornerY == mHeight) || (mCornerX == mWidth && mCornerY == 0)) mIsRTandLB = true; else mIsRTandLB = false; } public boolean doTouchEvent(MotionEvent event) { // TODO Auto-generated method stub if (event.getAction() == MotionEvent.ACTION_MOVE) { //System.out.println("doTouchEvent move"); /* mTouch.x = event.getX(); mTouch.y = event.getY(); this.postInvalidate();*/ } if (event.getAction() == MotionEvent.ACTION_DOWN) { //System.out.println("doTouchEvent down"); mTouch.x = event.getX(); mTouch.y = event.getY(); } if (event.getAction() == MotionEvent.ACTION_UP) { //System.out.println("doTouchEvent up"); if (canDragOver()) { startAnimation(0); } else { mTouch.x = mCornerX - 0.09f; mTouch.y = mCornerY - 0.09f; } this.postInvalidate(); } // return super.onTouchEvent(event); return true; } /** * Author : hmg25 Version: 1.0 Description : 求解直线P1P2和P3P4的交点坐标 */ public PointF getCross(PointF P1, PointF P2, PointF P3, PointF P4) { PointF CrossP = new PointF(); // 二元函数通式 y=ax+b float a1 = (P2.y - P1.y) / (P2.x - P1.x); float b1 = ((P1.x * P2.y) - (P2.x * P1.y)) / (P1.x - P2.x); float a2 = (P4.y - P3.y) / (P4.x - P3.x); float b2 = ((P3.x * P4.y) - (P4.x * P3.y)) / (P3.x - P4.x); CrossP.x = (b2 - b1) / (a1 - a2); CrossP.y = a1 * CrossP.x + b1; return CrossP; } private void calcPoints() { mMiddleX = (mTouch.x + mCornerX) / 2; mMiddleY = (mTouch.y + mCornerY) / 2; mBezierControl1.x = mMiddleX - (mCornerY - mMiddleY) * (mCornerY - mMiddleY) / (mCornerX - mMiddleX); mBezierControl1.y = mCornerY; mBezierControl2.x = mCornerX; mBezierControl2.y = mMiddleY - (mCornerX - mMiddleX) * (mCornerX - mMiddleX) / (mCornerY - mMiddleY); // Log.i("hmg", "mTouchX " + mTouch.x + " mTouchY " + mTouch.y); // Log.i("hmg", "mBezierControl1.x " + mBezierControl1.x // + " mBezierControl1.y " + mBezierControl1.y); // Log.i("hmg", "mBezierControl2.x " + mBezierControl2.x // + " mBezierControl2.y " + mBezierControl2.y); mBezierStart1.x = mBezierControl1.x - (mCornerX - mBezierControl1.x) / 2; mBezierStart1.y = mCornerY; // 当mBezierStart1.x < 0或mBezierStart1.x > 480时 // 如果继续翻页,会出现bug故在此限制 if (mTouch.x > 0 && mTouch.x < mWidth) { if (mBezierStart1.x < 0 || mBezierStart1.x > mWidth) { if (mBezierStart1.x < 0) mBezierStart1.x = mWidth - mBezierStart1.x; float f1 = Math.abs(mCornerX - mTouch.x); float f2 = mWidth * f1 / mBezierStart1.x; mTouch.x = Math.abs(mCornerX - f2); float f3 = Math.abs(mCornerX - mTouch.x) * Math.abs(mCornerY - mTouch.y) / f1; mTouch.y = Math.abs(mCornerY - f3); mMiddleX = (mTouch.x + mCornerX) / 2; mMiddleY = (mTouch.y + mCornerY) / 2; mBezierControl1.x = mMiddleX - (mCornerY - mMiddleY) * (mCornerY - mMiddleY) / (mCornerX - mMiddleX); mBezierControl1.y = mCornerY; mBezierControl2.x = mCornerX; mBezierControl2.y = mMiddleY - (mCornerX - mMiddleX) * (mCornerX - mMiddleX) / (mCornerY - mMiddleY); // Log.i("hmg", "mTouchX --> " + mTouch.x + " mTouchY--> " // + mTouch.y); // Log.i("hmg", "mBezierControl1.x-- " + mBezierControl1.x // + " mBezierControl1.y -- " + mBezierControl1.y); // Log.i("hmg", "mBezierControl2.x -- " + mBezierControl2.x // + " mBezierControl2.y -- " + mBezierControl2.y); mBezierStart1.x = mBezierControl1.x - (mCornerX - mBezierControl1.x) / 2; } } mBezierStart2.x = mCornerX; mBezierStart2.y = mBezierControl2.y - (mCornerY - mBezierControl2.y) / 2; mTouchToCornerDis = (float) Math.hypot((mTouch.x - mCornerX), (mTouch.y - mCornerY)); mBezierEnd1 = getCross(mTouch, mBezierControl1, mBezierStart1, mBezierStart2); mBezierEnd2 = getCross(mTouch, mBezierControl2, mBezierStart1, mBezierStart2); // Log.i("hmg", "mBezierEnd1.x " + mBezierEnd1.x + " mBezierEnd1.y " // + mBezierEnd1.y); // Log.i("hmg", "mBezierEnd2.x " + mBezierEnd2.x + " mBezierEnd2.y " // + mBezierEnd2.y); /* * mBeziervertex1.x 推导 * ((mBezierStart1.x+mBezierEnd1.x)/2+mBezierControl1.x)/2 化简等价于 * (mBezierStart1.x+ 2*mBezierControl1.x+mBezierEnd1.x) / 4 */ mBeziervertex1.x = (mBezierStart1.x + 2 * mBezierControl1.x + mBezierEnd1.x) / 4; mBeziervertex1.y = (2 * mBezierControl1.y + mBezierStart1.y + mBezierEnd1.y) / 4; mBeziervertex2.x = (mBezierStart2.x + 2 * mBezierControl2.x + mBezierEnd2.x) / 4; mBeziervertex2.y = (2 * mBezierControl2.y + mBezierStart2.y + mBezierEnd2.y) / 4; } private void drawCurrentPageArea(Canvas canvas, Bitmap bitmap, Path path) { mPath0.reset(); mPath0.moveTo(mBezierStart1.x, mBezierStart1.y); mPath0.quadTo(mBezierControl1.x, mBezierControl1.y, mBezierEnd1.x, mBezierEnd1.y); mPath0.lineTo(mTouch.x, mTouch.y); mPath0.lineTo(mBezierEnd2.x, mBezierEnd2.y); mPath0.quadTo(mBezierControl2.x, mBezierControl2.y, mBezierStart2.x, mBezierStart2.y); mPath0.lineTo(mCornerX, mCornerY); mPath0.close(); canvas.save(); canvas.clipPath(path, Region.Op.XOR); canvas.drawBitmap(bitmap, 0, 0, null); canvas.restore(); } private void drawNextPageAreaAndShadow(Canvas canvas, Bitmap bitmap) { mPath1.reset(); mPath1.moveTo(mBezierStart1.x, mBezierStart1.y); mPath1.lineTo(mBeziervertex1.x, mBeziervertex1.y); mPath1.lineTo(mBeziervertex2.x, mBeziervertex2.y); mPath1.lineTo(mBezierStart2.x, mBezierStart2.y); mPath1.lineTo(mCornerX, mCornerY); mPath1.close(); mDegrees = (float) Math.toDegrees(Math.atan2(mBezierControl1.x - mCornerX, mBezierControl2.y - mCornerY)); int leftx; int rightx; GradientDrawable mBackShadowDrawable; if (mIsRTandLB) { leftx = (int) (mBezierStart1.x); rightx = (int) (mBezierStart1.x + mTouchToCornerDis / 4); mBackShadowDrawable = mBackShadowDrawableLR; } else { leftx = (int) (mBezierStart1.x - mTouchToCornerDis / 4); rightx = (int) mBezierStart1.x; mBackShadowDrawable = mBackShadowDrawableRL; } canvas.save(); canvas.clipPath(mPath0); canvas.clipPath(mPath1, Region.Op.INTERSECT); canvas.drawBitmap(bitmap, 0, 0, null); canvas.rotate(mDegrees, mBezierStart1.x, mBezierStart1.y); mBackShadowDrawable.setBounds(leftx, (int) mBezierStart1.y, rightx, (int) (mMaxLength + mBezierStart1.y)); mBackShadowDrawable.draw(canvas); canvas.restore(); } public void setBitmaps(Bitmap bm1, Bitmap bm2) { mCurPageBitmap = bm1; mNextPageBitmap = bm2; } public void setScreen(int w, int h) { mWidth = w; mHeight = h; } @Override protected void onDraw(Canvas canvas) { //System.out.println("onDraw"); canvas.drawColor(0xFFAAAAAA); calcPoints(); drawCurrentPageArea(canvas, mCurPageBitmap, mPath0); drawNextPageAreaAndShadow(canvas, mNextPageBitmap); //drawCurrentPageShadow(canvas); //drawCurrentBackArea(canvas, mCurPageBitmap); } /** * Author : hmg25 Version: 1.0 Description : 创建阴影的GradientDrawable */ private void createDrawable() { int[] color = { 0x333333, 0xb0333333 }; mFolderShadowDrawableRL = new GradientDrawable( GradientDrawable.Orientation.RIGHT_LEFT, color); mFolderShadowDrawableRL .setGradientType(GradientDrawable.LINEAR_GRADIENT); mFolderShadowDrawableLR = new GradientDrawable( GradientDrawable.Orientation.LEFT_RIGHT, color); mFolderShadowDrawableLR .setGradientType(GradientDrawable.LINEAR_GRADIENT); mBackShadowColors = new int[] { 0xff111111, 0x111111 }; mBackShadowDrawableRL = new GradientDrawable( GradientDrawable.Orientation.RIGHT_LEFT, mBackShadowColors); mBackShadowDrawableRL.setGradientType(GradientDrawable.LINEAR_GRADIENT); mBackShadowDrawableLR = new GradientDrawable( GradientDrawable.Orientation.LEFT_RIGHT, mBackShadowColors); mBackShadowDrawableLR.setGradientType(GradientDrawable.LINEAR_GRADIENT); mFrontShadowColors = new int[] { 0x80111111, 0x111111 }; mFrontShadowDrawableVLR = new GradientDrawable( GradientDrawable.Orientation.LEFT_RIGHT, mFrontShadowColors); mFrontShadowDrawableVLR .setGradientType(GradientDrawable.LINEAR_GRADIENT); mFrontShadowDrawableVRL = new GradientDrawable( GradientDrawable.Orientation.RIGHT_LEFT, mFrontShadowColors); mFrontShadowDrawableVRL .setGradientType(GradientDrawable.LINEAR_GRADIENT); mFrontShadowDrawableHTB = new GradientDrawable( GradientDrawable.Orientation.TOP_BOTTOM, mFrontShadowColors); mFrontShadowDrawableHTB .setGradientType(GradientDrawable.LINEAR_GRADIENT); mFrontShadowDrawableHBT = new GradientDrawable( GradientDrawable.Orientation.BOTTOM_TOP, mFrontShadowColors); mFrontShadowDrawableHBT .setGradientType(GradientDrawable.LINEAR_GRADIENT); } public void computeScroll() { super.computeScroll(); if (mScroller.computeScrollOffset()) { float x = mScroller.getCurrX(); float y = mScroller.getCurrY(); mTouch.x = x; mTouch.y = y; postInvalidate(); } } private void startAnimation(int delayMillis) { int dx, dy; // dx 水平方向滑动的距离,负值会使滚动向左滚动 // dy 垂直方向滑动的距离,负值会使滚动向上滚动 if (mCornerX > 0) { dx = -(int) (mWidth + mTouch.x); } else { dx = (int) (mWidth - mTouch.x + mWidth); } if (mCornerY > 0) { dy = (int) (mHeight - mTouch.y); } else { dy = (int) (1 - mTouch.y); // 防止mTouch.y最终变为0 } mScroller.startScroll((int) mTouch.x, (int) mTouch.y, dx, dy, delayMillis); } public void abortAnimation() { if (!mScroller.isFinished()) { mScroller.abortAnimation(); } } public boolean canDragOver() { //if (mTouchToCornerDis > mWidth / 10) return true; //return false; } /** * Author : hmg25 Version: 1.0 Description : 是否从左边翻向右边 */ public boolean DragToRight(float tmpX) { if(tmpX >=turntest.width /2) //(mCornerX > 0) { //System.out.println("--to right"); return true; } return false; } public boolean DragToLeft(float tmpX) { if(tmpX < turntest.width/2) //(mCornerX > 0) { //System.out.println("--to left"); return true; } return false; } }
ReadChapter.java
package com2.aiai.www; import java.io.IOException; import com2.aiai.www.R; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.view.Window; import android.view.WindowManager; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.Toast; public class ReadChapter extends Activity { /** Called when the activity is first created. */ private PageWidget mPageWidget; Bitmap mCurPageBitmap, mNextPageBitmap; Canvas mCurPageCanvas, mNextPageCanvas; BookPageFactory pagefactory; private ListView listView; public static int chapterNum=0; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //if(pd.isShowing()) requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); mPageWidget = new PageWidget(this); setContentView(mPageWidget); mCurPageBitmap = Bitmap.createBitmap(turntest.width, turntest.height, Bitmap.Config.ARGB_8888); mNextPageBitmap = Bitmap .createBitmap(turntest.width, turntest.height, Bitmap.Config.ARGB_8888); mCurPageCanvas = new Canvas(mCurPageBitmap); mNextPageCanvas = new Canvas(mNextPageBitmap); pagefactory = new BookPageFactory(turntest.width, turntest.height); pagefactory.setBgBitmap(BitmapFactory.decodeResource( this.getResources(), R.drawable.bg)); try { String str="/data/data/com2.aiai.www/databases/chapter"+(chapterNum+3); pagefactory.openbook(str); pagefactory.mPageTotal=pagefactory.getTotalPages(); pagefactory.onDraw(mCurPageCanvas); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); Toast.makeText(this, "电子书不存在", Toast.LENGTH_SHORT).show(); } mPageWidget.setBitmaps(mCurPageBitmap, mCurPageBitmap); mPageWidget.postInvalidate(); mPageWidget.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent e) { // TODO Auto-generated method stub float tmpX = e.getX(); float tmpY = e.getY(); System.out.println("tmpx="+tmpX); boolean ret=false; if (v == mPageWidget) { if (e.getAction() == MotionEvent.ACTION_DOWN) { mPageWidget.abortAnimation(); mPageWidget.calcCornerXY(e.getX(), e.getY()); pagefactory.onDraw(mCurPageCanvas); if (mPageWidget.DragToLeft(tmpX)) { try { pagefactory.prePage(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } if(pagefactory.isfirstPage())return false; pagefactory.onDraw(mNextPageCanvas); } else if (mPageWidget.DragToRight(tmpX)){ try { pagefactory.nextPage(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } if(pagefactory.islastPage())return false; pagefactory.onDraw(mNextPageCanvas); } else { return false; } mPageWidget.setBitmaps(mCurPageBitmap, mNextPageBitmap); } ret = mPageWidget.doTouchEvent(e); return ret; } return false; } }); } }
turntest.java
package com2.aiai.www; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import com2.aiai.www.R; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.os.Bundle; import android.view.Display; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.view.Window; import android.view.WindowManager; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.Toast; public class turntest extends Activity { /** Called when the activity is first created. */ private PageWidget mPageWidget; Bitmap mCurPageBitmap, mNextPageBitmap; Canvas mCurPageCanvas, mNextPageCanvas; BookPageFactory pagefactory; private ListView listView; public static int height; public static int width; public final static String FILE_PATH = "/data/data/com2.aiai.www/databases/"; public final static String FILE_NAME = "chapter"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /*requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);*/ Display display = getWindowManager().getDefaultDisplay(); width = display.getWidth(); height = display.getHeight(); System.out.println("width="+width+",height="+height); /* if(240==width && 480==height) //HVGA setContentView(R.layout.main240_480); else if(240==width && 432==height) //WQVGA432 setContentView(R.layout.main240_432); else if(240==width && 320==height)//QVGA setContentView(R.layout.main240_320); else if(480==width && 800==height)//WVGA800 setContentView(R.layout.main480_800); else if(480==width && 854==height)//WVGA854 setContentView(R.layout.main480_854); else if(240==width && 400==height) //WQVGA400 setContentView(R.layout.main240_400); else setContentView(R.layout.main);*/ String[]strs={"第一 至 第十 回","第十一 至 第二十 回","第二十一 至 第三十 回", "第三十一 至 第四十 回","第四十一 至 第五十 回","第五十一 至 第六十 回", "第六十一 至 第七十 回","第七十一 至 第八十 回","第八十一 至 第九十 回", "第九十一 至 第一百 回",}; listView=new ListView(this); listView.setAdapter(new ArrayAdapter<String>(this, R.layout.my_simple_list_item_1,strs)); listView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub //Intent intent =new intent(); //Intent intent = new Intent(turntest.this,ChapterA.class); //startActivity(intent); if(arg2>=0 &&arg2<=9) { ChapterIndex.chapterIndex = 10*arg2; startActivity(new Intent(turntest.this, ChapterIndex.class)); } // intent.setClass(content,ChapterA.class); // content.startActivity(intent); // intent.setClass(context, ChapterA.class); } }); //listView.setBackgroundResource(R.drawable.bg); //listView.setBackgroundColor(R.color.white); setContentView(listView); copyDB(); } public void copyDB(){ int [] arr_id={ R.raw.chapter1,R.raw.chapter2,R.raw.chapter3,R.raw.chapter4,R.raw.chapter5, R.raw.chapter6,R.raw.chapter7,R.raw.chapter8,R.raw.chapter9,R.raw.chapter10, R.raw.chapter11,R.raw.chapter12,R.raw.chapter13,R.raw.chapter14,R.raw.chapter15, R.raw.chapter16,R.raw.chapter17,R.raw.chapter18,R.raw.chapter19,R.raw.chapter20, R.raw.chapter21,R.raw.chapter22,R.raw.chapter23,R.raw.chapter24,R.raw.chapter25, R.raw.chapter26,R.raw.chapter27,R.raw.chapter28,R.raw.chapter29,R.raw.chapter30, R.raw.chapter31,R.raw.chapter32,R.raw.chapter33,R.raw.chapter34,R.raw.chapter35, R.raw.chapter36,R.raw.chapter37,R.raw.chapter38,R.raw.chapter39,R.raw.chapter40, R.raw.chapter41,R.raw.chapter42,R.raw.chapter43,R.raw.chapter44,R.raw.chapter45, R.raw.chapter46,R.raw.chapter47,R.raw.chapter48,R.raw.chapter49,R.raw.chapter50, R.raw.chapter51,R.raw.chapter52,R.raw.chapter53,R.raw.chapter54,R.raw.chapter55, R.raw.chapter56,R.raw.chapter57,R.raw.chapter58,R.raw.chapter59,R.raw.chapter60, R.raw.chapter61,R.raw.chapter62,R.raw.chapter63,R.raw.chapter64,R.raw.chapter65, R.raw.chapter66,R.raw.chapter67,R.raw.chapter68,R.raw.chapter69,R.raw.chapter70, R.raw.chapter71,R.raw.chapter72,R.raw.chapter73,R.raw.chapter74,R.raw.chapter75, R.raw.chapter76,R.raw.chapter77,R.raw.chapter78,R.raw.chapter79,R.raw.chapter80, R.raw.chapter81,R.raw.chapter82,R.raw.chapter83,R.raw.chapter84,R.raw.chapter85, R.raw.chapter86,R.raw.chapter87,R.raw.chapter88,R.raw.chapter89,R.raw.chapter90, R.raw.chapter91,R.raw.chapter92,R.raw.chapter93,R.raw.chapter94,R.raw.chapter95, R.raw.chapter96,R.raw.chapter97,R.raw.chapter98,R.raw.chapter99,R.raw.chapter100, R.raw.chapter101,R.raw.chapter102 }; File dir = new File(FILE_PATH); if(!dir.exists()){ dir.mkdirs(); } for(int i=0; i<102; i++) { String file_name=FILE_NAME+(i+1); File file = new File(FILE_PATH,file_name); int id = 0; try{ if(!file.exists()){ System.out.println(file_name); InputStream is = this.getResources().openRawResource( arr_id[i]/*R.raw.attribution*/); //欲导入的数据库 FileOutputStream fos = new FileOutputStream(file); byte[] buffer = new byte[8*1024]; int count = 0; while ((count = is.read(buffer)) > 0) { fos.write(buffer, 0, count); } fos.flush(); fos.close(); is.close(); } //return true; }catch(Exception e){ e.printStackTrace(); //return false; } } //return false; } }
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com2.aiai.www" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".turntest" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".ChapterIndex" /> <activity android:name="com2.aiai.www.ReadChapter" /> </application> <uses-sdk android:minSdkVersion="4" /> </manifest>
my_simple_list_item_1.xml
<?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2006 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/text1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:textColor="#000000" android:gravity="center_vertical" android:paddingLeft="6dip" android:minHeight="?android:attr/listPreferredItemHeight" android:background="@drawable/selector_list_item_mid" android:drawableRight="@drawable/ic_into_icon" />
<?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2006 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/text1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:textColor="#000000" android:gravity="center_vertical" android:paddingLeft="6dip" android:minHeight="?android:attr/listPreferredItemHeight" android:background="@drawable/selector_list_item_mid" />
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/bg_list_item_mid_pressed" android:state_pressed="true"/> <item android:drawable="@drawable/bg_list_item_mid_pressed" android:state_focused="true"/> <item android:drawable="@drawable/bg_list_item_mid_normal"/> </selector>