1. 程式人生 > >有寵商城Android端原始碼(更新版)

有寵商城Android端原始碼(更新版)

【前言】願你在迷茫時,堅信你的珍貴,愛你所愛,行你所行,聽從你的新,無問西東。

【專案介紹】之前是有發過這個專案的,請戳這裡,當時這個專案的引導頁已經做得非常不好,功能雖然已經實現,但是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,有需要的小夥伴可以聯絡我,由有公司擔保,童叟無欺!