Android4.4 SystemUI分析之DessertCase

來源:互聯網
上載者:User

Android4.4 SystemUI分析之DessertCase

在SystemUI中有一個Activity可以顯示所有的Logo

這個Activity涉及到的表徵圖存放在SystemUI/res/drawable-nodpi目錄下

在這裡我自己寫了個小的測試程式,把相關的檔案拿出來

DessertCase.java、DessertCaseDream.java、DessertCaseView.java,只要是在DessertCaseView這個View中動態改變表徵圖的位置

只要在測試程式中啟動DessertCase.java就可以了

 

Intent intent = new Intent(getApplicationContext(),DessertCase.class);startActivity(intent);

 

 

/* * Copyright (C) 2013 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. */package com.dzt.testapp.dessert;import android.app.Activity;import android.content.ComponentName;import android.content.pm.PackageManager;import android.util.Slog;public class DessertCase extends Activity {DessertCaseView mView;@Overridepublic void onStart() {super.onStart();PackageManager pm = getPackageManager();final ComponentName cn = new ComponentName(this, DessertCaseDream.class);if (pm.getComponentEnabledSetting(cn) != PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {Slog.v("DessertCase", "ACHIEVEMENT UNLOCKED");pm.setComponentEnabledSetting(cn,PackageManager.COMPONENT_ENABLED_STATE_ENABLED,PackageManager.DONT_KILL_APP);}mView = new DessertCaseView(this);DessertCaseView.RescalingContainer container = new DessertCaseView.RescalingContainer(this);container.setView(mView);setContentView(container);}@Overridepublic void onResume() {super.onResume();mView.postDelayed(new Runnable() {public void run() {mView.start();}}, 1000);}@Overridepublic void onPause() {super.onPause();mView.stop();}}
自訂的View,實現一些動畫

 

 

/* * Copyright (C) 2013 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. */package com.dzt.testapp.dessert;import android.animation.Animator;import android.animation.AnimatorListenerAdapter;import android.animation.AnimatorSet;import android.animation.ObjectAnimator;import android.content.Context;import android.content.res.Resources;import android.graphics.*;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.Drawable;import android.os.Handler;import android.util.AttributeSet;import android.util.Log;import android.util.SparseArray;import android.view.View;import android.view.animation.AccelerateInterpolator;import android.view.animation.AnticipateOvershootInterpolator;import android.view.animation.DecelerateInterpolator;import android.widget.FrameLayout;import android.widget.ImageView;import java.util.HashSet;import java.util.Set;import com.dzt.testapp.R;public class DessertCaseView extends FrameLayout {    private static final String TAG = DessertCaseView.class.getSimpleName();    private static final boolean DEBUG = false;    static final int START_DELAY = 5000;    static final int DELAY = 2000;    static final int DURATION = 500;    private static final int TAG_POS = 0x2000001;    private static final int TAG_SPAN = 0x2000002;    private static final int[] PASTRIES = {            R.drawable.dessert_kitkat,      // used with permission            R.drawable.dessert_android,     // thx irina    };    private static final int[] RARE_PASTRIES = {            R.drawable.dessert_cupcake,     // 2009            R.drawable.dessert_donut,       // 2009            R.drawable.dessert_eclair,      // 2009            R.drawable.dessert_froyo,       // 2010            R.drawable.dessert_gingerbread, // 2010            R.drawable.dessert_honeycomb,   // 2011            R.drawable.dessert_ics,         // 2011            R.drawable.dessert_jellybean,   // 2012    };    private static final int[] XRARE_PASTRIES = {            R.drawable.dessert_petitfour,   // the original and still delicious            R.drawable.dessert_donutburger, // remember kids, this was long before cronuts            R.drawable.dessert_flan,        //     sholes final approach                                            //     landing gear punted to flan                                            //     runway foam glistens                                            //         -- mcleron            R.drawable.dessert_keylimepie,  // from an alternative timeline    };    private static final int[] XXRARE_PASTRIES = {            R.drawable.dessert_zombiegingerbread, // thx hackbod            R.drawable.dessert_dandroid,    // thx morrildl            R.drawable.dessert_jandycane,   // thx nes    };    private static final int NUM_PASTRIES = PASTRIES.length + RARE_PASTRIES.length            + XRARE_PASTRIES.length + XXRARE_PASTRIES.length;    private SparseArray mDrawables = new SparseArray(NUM_PASTRIES);    private static final float[] MASK = {            0f,  0f,  0f,  0f, 255f,            0f,  0f,  0f,  0f, 255f,            0f,  0f,  0f,  0f, 255f,            1f,  0f,  0f,  0f, 0f    };    private static final float[] ALPHA_MASK = {            0f,  0f,  0f,  0f, 255f,            0f,  0f,  0f,  0f, 255f,            0f,  0f,  0f,  0f, 255f,            0f,  0f,  0f,  1f, 0f    };    private static final float[] WHITE_MASK = {            0f,  0f,  0f,  0f, 255f,            0f,  0f,  0f,  0f, 255f,            0f,  0f,  0f,  0f, 255f,            -1f,  0f,  0f,  0f, 255f    };    public static final float SCALE = 0.25f; // natural display size will be SCALE*mCellSize    private static final float PROB_2X = 0.33f;    private static final float PROB_3X = 0.1f;    private static final float PROB_4X = 0.01f;    private boolean mStarted;    private int mCellSize;    private int mWidth, mHeight;    private int mRows, mColumns;    private View[] mCells;    private final Set mFreeList = new HashSet();    private final Handler mHandler = new Handler();    private final Runnable mJuggle = new Runnable() {        @Override        public void run() {            final int N = getChildCount();            final int K = 1; //irand(1,3);            for (int i=0; i T pick(T[] a) {        return a[(int)(Math.random()*a.length)];    }     T pick(SparseArray sa) {        return sa.valueAt((int)(Math.random()*sa.size()));    }    float[] hsv = new float[] { 0, 1f, .85f };    int random_color() {//        return 0xFF000000 | (int) (Math.random() * (float) 0xFFFFFF); // totally random        final int COLORS = 12;        hsv[0] = irand(0,COLORS) * (360f/COLORS);        return Color.HSVToColor(hsv);    }    @Override    protected synchronized void onSizeChanged (int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        if (mWidth == w && mHeight == h) return;        final boolean wasStarted = mStarted;        if (wasStarted) {            stop();        }        mWidth = w;        mHeight = h;        mCells = null;        removeAllViewsInLayout();        mFreeList.clear();        mRows = mHeight / mCellSize;        mColumns = mWidth / mCellSize;        mCells = new View[mRows * mColumns];        if (DEBUG) Log.v(TAG, String.format("New dimensions: %dx%d", mColumns, mRows));        setScaleX(SCALE);        setScaleY(SCALE);        setTranslationX(0.5f * (mWidth - mCellSize * mColumns) * SCALE);        setTranslationY(0.5f * (mHeight - mCellSize * mRows) * SCALE);        for (int j=0; j 0) {                final float s = (Integer) v.getTag(TAG_SPAN);                v.setScaleX(0.5f * s);                v.setScaleY(0.5f * s);                v.setAlpha(0f);                v.animate().withLayer().scaleX(s).scaleY(s).alpha(1f).setDuration(animationLen);            }        }    }    public void place(View v, boolean animate) {        place(v, new Point(irand(0, mColumns), irand(0, mRows)), animate);    }    // we don't have .withLayer() on general Animators    private final Animator.AnimatorListener makeHardwareLayerListener(final View v) {        return new AnimatorListenerAdapter() {            @Override            public void onAnimationStart(Animator animator) {                /// M: [ALPS01271500] Check if this view is currently attached to a window.                if (!v.isAttachedToWindow()) return;                v.setLayerType(View.LAYER_TYPE_HARDWARE, null);                v.buildLayer();            }            @Override            public void onAnimationEnd(Animator animator) {                /// M: [ALPS01271500] Check if this view is currently attached to a window.                if (!v.isAttachedToWindow()) return;                v.setLayerType(View.LAYER_TYPE_NONE, null);            }        };    }    private final HashSet tmpSet = new HashSet();    public synchronized void place(View v, Point pt, boolean animate) {        final int i = pt.x;        final int j = pt.y;        final float rnd = frand();        if (v.getTag(TAG_POS) != null) {            for (final Point oc : getOccupied(v)) {                mFreeList.add(oc);                mCells[oc.y*mColumns + oc.x] = null;            }        }        int scale = 1;        if (rnd < PROB_4X) {            if (!(i >= mColumns-3 || j >= mRows-3)) {                scale = 4;            }        } else if (rnd < PROB_3X) {            if (!(i >= mColumns-2 || j >= mRows-2)) {                scale = 3;            }        } else if (rnd < PROB_2X) {            if (!(i == mColumns-1 || j == mRows-1)) {                scale = 2;            }        }        v.setTag(TAG_POS, pt);        v.setTag(TAG_SPAN, scale);        tmpSet.clear();        final Point[] occupied = getOccupied(v);        for (final Point oc : occupied) {            final View squatter = mCells[oc.y*mColumns + oc.x];            if (squatter != null) {                tmpSet.add(squatter);            }        }        for (final View squatter : tmpSet) {            for (final Point sq : getOccupied(squatter)) {                mFreeList.add(sq);                mCells[sq.y*mColumns + sq.x] = null;            }            if (squatter != v) {                squatter.setTag(TAG_POS, null);                if (animate) {                    squatter.animate().withLayer()                            .scaleX(0.5f).scaleY(0.5f).alpha(0)                            .setDuration(DURATION)                            .setInterpolator(new AccelerateInterpolator())                            .setListener(new Animator.AnimatorListener() {                                public void onAnimationStart(Animator animator) { }                                public void onAnimationEnd(Animator animator) {                                    removeView(squatter);                                }                                public void onAnimationCancel(Animator animator) { }                                public void onAnimationRepeat(Animator animator) { }                            })                            .start();                } else {                    removeView(squatter);                }            }        }        for (final Point oc : occupied) {            mCells[oc.y*mColumns + oc.x] = v;            mFreeList.remove(oc);        }        final float rot = (float)irand(0, 4) * 90f;        if (animate) {            v.bringToFront();            AnimatorSet set1 = new AnimatorSet();            set1.playTogether(                    ObjectAnimator.ofFloat(v, View.SCALE_X, (float) scale),                    ObjectAnimator.ofFloat(v, View.SCALE_Y, (float) scale)            );            set1.setInterpolator(new AnticipateOvershootInterpolator());            set1.setDuration(DURATION);            AnimatorSet set2 = new AnimatorSet();            set2.playTogether(                    ObjectAnimator.ofFloat(v, View.ROTATION, rot),                    ObjectAnimator.ofFloat(v, View.X, i* mCellSize + (scale-1) * mCellSize /2),                    ObjectAnimator.ofFloat(v, View.Y, j* mCellSize + (scale-1) * mCellSize /2)            );            set2.setInterpolator(new DecelerateInterpolator());            set2.setDuration(DURATION);            set1.addListener(makeHardwareLayerListener(v));            set1.start();            set2.start();        } else {            v.setX(i * mCellSize + (scale-1) * mCellSize /2);            v.setY(j * mCellSize + (scale-1) * mCellSize /2);            v.setScaleX((float) scale);            v.setScaleY((float) scale);            v.setRotation(rot);        }    }    private Point[] getOccupied(View v) {        final int scale = (Integer) v.getTag(TAG_SPAN);        final Point pt = (Point)v.getTag(TAG_POS);        if (pt == null || scale == 0) return new Point[0];        final Point[] result = new Point[scale * scale];        int p=0;        for (int i=0; i在Activity onResume時會建立線程調用

 

 

public void start() {        if (!mStarted) {            mStarted = true;            fillFreeList(DURATION * 4);        }        mHandler.postDelayed(mJuggle, START_DELAY);    }
同時也會建立一個線程迴圈調用動畫播放

 

 

private final Runnable mJuggle = new Runnable() {        @Override        public void run() {            final int N = getChildCount();            final int K = 1; //irand(1,3);            for (int i=0; i

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.