有寵商城Android端原始碼(更新版)
阿新 • • 發佈:2019-01-31
【前言】願你在迷茫時,堅信你的珍貴,愛你所愛,行你所行,聽從你的新,無問西東。
【專案介紹】之前是有發過這個專案的,請戳這裡,當時這個專案的引導頁已經做得非常不好,功能雖然已經實現,但是bug極多,很多小夥伴給我留言說讓我改進一下,後來抽了個時間就改進了一些東西:
1.封裝了一些BaseActivity和BaseFragment,當時寫這個專案沒有這些思想,新頁面就是單獨的Activity和Fragment;
2.改進了引導頁的四個動畫,利用RecyclerView去實現ViewPager,一次只能翻一頁,並且滑動停止開始載入動畫,動畫的載入也沒有采用幀動畫,畢竟 120多張圖,幀動畫誰用誰知道Out of memory,後來網上Google了一下,選擇SurfaceView去實現這個動畫,結果非常完美和流暢;
3.多個頁面的Banner改進,之前使用Handler去實現的,當時想著是自己去體會一下Handler的用法,後來瞭解了記憶體洩漏這個東西后,還是採用了比較成熟的三方框架。
【專案中心】專案中最大的亮點我覺得就是利用SurfaceView去實現幀動畫,自己覺得非常棒,下面是原始碼:
public class LeaderView extends SurfaceView implements SurfaceHolder.Callback, Runnable { private SurfaceHolder mSurfaceHolder; private boolean mIsThreadRunning = true; // 執行緒執行開關 public static boolean mIsDestroy = false;// 是否已經銷燬 private int[] mBitmapResourceIds;// 用於播放動畫的圖片資源id陣列 private ArrayList<String> mBitmapResourcePaths;// 用於播放動畫的圖片資源path陣列 private int totalCount;//資源總數 private Canvas mCanvas; private Bitmap mBitmap;// 顯示的圖片 private int mCurrentIndext;// 當前動畫播放的位置 private int mGapTime = 50;// 每幀動畫持續存在的時間 private boolean mIsRepeat = false; private OnFrameFinishedListener mOnFrameFinishedListener;// 動畫監聽事件 public LeaderView(Context context) { this(context, null); initView(); } public LeaderView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initView(); } public LeaderView(Context context, AttributeSet attrs) { this(context, attrs, 0); initView(); } private void initView() { mSurfaceHolder = this.getHolder(); mSurfaceHolder.addCallback(this); // 白色背景 setZOrderOnTop(true); // setZOrderMediaOverlay(true); // mSurfaceHolder.setFormat(PixelFormat.TRANSLUCENT); } @Override public void surfaceCreated(SurfaceHolder holder) { } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { // 當surfaceView銷燬時, 停止執行緒的執行. 避免surfaceView銷燬了執行緒還在執行而報錯. // mIsThreadRunning = false; // try { // Thread.sleep(mGapTime); // } catch (InterruptedException e) { // e.printStackTrace(); // } // // mIsDestroy = true; } /** * 製圖方法 */ private void drawView() { // 無資原始檔退出 if (mBitmapResourceIds == null && mBitmapResourcePaths == null) { Log.e("info", "the bitmapsrcIDs is null"); mIsThreadRunning = false; return; } // 鎖定畫布 if (mSurfaceHolder != null) { mCanvas = mSurfaceHolder.lockCanvas(); } try { if (mSurfaceHolder != null && mCanvas != null) { mCanvas.drawColor(Color.WHITE); if (mBitmapResourceIds != null && mBitmapResourceIds.length > 0) mBitmap = BitmapFactory.decodeResource(getResources(), mBitmapResourceIds[mCurrentIndext]); else if (mBitmapResourcePaths != null && mBitmapResourcePaths.size() > 0) { mBitmap = BitmapFactory.decodeFile(mBitmapResourcePaths.get(mCurrentIndext)); } Paint paint = new Paint(); paint.setAntiAlias(true); paint.setStyle(Paint.Style.STROKE); Rect mSrcRect, mDestRect; mSrcRect = new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight()); mDestRect = new Rect(0, 0, getWidth(), getHeight()); mCanvas.drawBitmap(mBitmap, mSrcRect, mDestRect, paint); // 播放到最後一張圖片 if (mCurrentIndext == totalCount - 1) { //播放到最後一張,當前index置零 // mCurrentIndext = 0; if (mIsRepeat) { mCurrentIndext = 0; }else { stop(); } } } } catch (Exception e) { e.printStackTrace(); } finally { mCurrentIndext++; if (mCurrentIndext >= totalCount) { mCurrentIndext = 0; } if (mCanvas != null) { // 將畫布解鎖並顯示在螢幕上 if (mSurfaceHolder != null) { mSurfaceHolder.unlockCanvasAndPost(mCanvas); } } if (mBitmap != null) { // 收回圖片 mBitmap.recycle(); } } } @Override public void run() { if (mOnFrameFinishedListener != null) { mOnFrameFinishedListener.onStart(); } // 每隔150ms重新整理螢幕 while (mIsThreadRunning) { drawView(); try { Thread.sleep(mGapTime); } catch (Exception e) { e.printStackTrace(); } } if (mOnFrameFinishedListener != null) { mOnFrameFinishedListener.onStop(); } } /** * 開始動畫 */ public void start() { if (!mIsDestroy) { mCurrentIndext = 0; mIsThreadRunning = true; new Thread(this).start(); } else { // 如果SurfaceHolder已經銷燬丟擲該異常 try { throw new Exception("IllegalArgumentException:Are you sure the SurfaceHolder is not destroyed"); } catch (Exception e) { e.printStackTrace(); } } } /** * 設定動畫播放素材的id * * @param bitmapResourceIds 圖片資源id */ public void setBitmapResoursID(int[] bitmapResourceIds) { this.mBitmapResourceIds = bitmapResourceIds; totalCount = bitmapResourceIds.length; } /** * 設定動畫播放素材的路徑 * * @param bitmapResourcePaths */ public void setmBitmapResourcePath(ArrayList bitmapResourcePaths) { this.mBitmapResourcePaths = bitmapResourcePaths; totalCount = bitmapResourcePaths.size(); } /** * 設定每幀時間 */ public void setGapTime(int gapTime) { this.mGapTime = gapTime; } /** * 結束動畫 */ public void stop() { mIsThreadRunning = false; } /** * 繼續動畫 */ public void reStart() { mIsThreadRunning = false; } /** * 設定動畫監聽器 */ public void setOnFrameFinisedListener(OnFrameFinishedListener onFrameFinishedListener) { this.mOnFrameFinishedListener = onFrameFinishedListener; } /** * 動畫監聽器 * * @author qike */ public interface OnFrameFinishedListener { /** * 動畫開始 */ void onStart(); /** * 動畫結束 */ void onStop(); } /** * 當用戶點選返回按鈕時,停止執行緒,反轉記憶體溢位 */ @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // 當按返回鍵時,將執行緒停止,避免surfaceView銷燬了,而執行緒還在執行而報錯 if (keyCode == KeyEvent.KEYCODE_BACK) { mIsThreadRunning = false; } return super.onKeyDown(keyCode, event); } }
【APK掃碼下載】
【專案完整地址】https://github.com/548986/Pet.git
【聯絡方式】如果你有什麼好的建議或者疑問可以聯絡我!1070138445~順便給自己打一波廣告,本人承接本科和研究生的畢業設計,涵蓋Java和Android,有需要的小夥伴可以聯絡我,由有公司擔保,童叟無欺!