編輯:關於Android編程
編輯(11/27/12):添加一個視頻演示結果在Nexus 7運行Android 4.1系統
過去一年,ActionBar范式已經成為一個重要的組成部分的過程中,設計和開發一個Android應用程序。事實上,有許多優點,ActionBar幫助開發人員在其應用程序能否經得住時間的考驗。它包含相關操作,可以很容易地定制,是高度可伸縮的,等等。正因為如此,一個人應該總是考慮使用ActionBar UI模式在設計過程在創建一個新的Android應用程序。
ActionBar功能很多有趣的樣式的api。這些api允許您品牌你應用程序,這樣,適合你的設計,同時還被辨認在其他的應用程序。簡單來說,就是幾乎沒有限制你能做什麼和一個ActionBar。直到你嘗試做一些更高級的。。。
為了確保這是可能我創建了一個小小的應用程序與一個ActionBar。我迅速建立了一個AnimationDrawable,開始用一個簡單的調用start()方法,並使用它作為ActionBar的背景。結果很令人失望,因為它不是在所有動畫。探索ActionBarContainer(一個非公有制視圖支持ActionBar)源代碼我注意到它沒有登記callback1我可拉的:
[java]
public void setPrimaryBackground(Drawable bg) {
mBackground = bg;
invalidate();
}
public void setPrimaryBackground(Drawable bg) {
mBackground = bg;
invalidate();
}
結果,可拉的沒有辦法通知封閉視圖以固定時間間隔重繪本身。從我的角度來看,這是一個想要的行為,以避免這些web -的- - - - 90的紅色到黃色閃爍ActionBars。我終於決定推遲到未來版本的動畫。
最近我回到了這個特性/增強,開始開發一個新的Animatable可提取測試目的。這個非常基本的繪圖改變顏色和變化的變化在一個光滑的時尚:
[java]
public class ColorAnimationDrawable extends Drawable implements Animatable {
private static final long FRAME_DURATION = 1000 / 60;
private static final long ANIMATION_DURATION = 1500;
private static final int ACCCENT_COLOR = 0x33FFFFFF;
private static final int DIM_COLOR = 0x33000000;
private static final Random mRandom = new Random();
private final Paint mPaint = new Paint();
private boolean mIsRunning;
private int mStartColor;
private int mEndColor;
private int mCurrentColor;
private long mStartTime;
@Override
public void draw(Canvas canvas) {
final Rect bounds = getBounds();
mPaint.setColor(mCurrentColor);
canvas.drawRect(bounds, mPaint);
mPaint.setColor(ACCCENT_COLOR);
canvas.drawRect(bounds.left, bounds.top, bounds.right, bounds.top + 1, mPaint);
mPaint.setColor(DIM_COLOR);
canvas.drawRect(bounds.left, bounds.bottom - 2, bounds.right, bounds.bottom, mPaint);
}
@Override
public void setAlpha(int alpha) {
oops("setAlpha(int)");
}
@Override
public void setColorFilter(ColorFilter cf) {
oops("setColorFilter(ColorFilter)");
}
@Override
public int getOpacity() {
return PixelFormat.TRANSPARENT;
}
@Override
public void start() {
if (!isRunning()) {
mIsRunning = true;
mStartTime = AnimationUtils.currentAnimationTimeMillis();
mStartColor = randomColor();
mEndColor = randomColor();
scheduleSelf(mUpdater, SystemClock.uptimeMillis() + FRAME_DURATION);
invalidateSelf();
}
}
@Override
public void stop() {
if (isRunning()) {
unscheduleSelf(mUpdater);
mIsRunning = false;
}
}
@Override
public boolean isRunning() {
return mIsRunning;
}
private void oops(String message) {
throw new UnsupportedOperationException("ColorAnimationDrawable doesn't support " + message);
}
private static int randomColor() {
return mRandom.nextInt() & 0x00FFFFFF;
}
private static int evaluate(float fraction, int startValue, int endValue) {
return (int) (startValue + fraction * (endValue - startValue));
}
private final Runnable mUpdater = new Runnable() {
@Override
public void run() {
long now = AnimationUtils.currentAnimationTimeMillis();
long duration = now - mStartTime;
if (duration >= ANIMATION_DURATION) {
mStartColor = mEndColor;
mEndColor = randomColor();
mStartTime = now;
mCurrentColor = mStartColor;
} else {
float fraction = duration / (float) ANIMATION_DURATION;
//@formatter:off
mCurrentColor = Color.rgb(
evaluate(fraction, Color.red(mStartColor), Color.red(mEndColor)), // red
evaluate(fraction, Color.green(mStartColor), Color.green(mEndColor)), // green
evaluate(fraction, Color.blue(mStartColor), Color.blue(mEndColor))); // blue
//@formatter:on
}
scheduleSelf(mUpdater, SystemClock.uptimeMillis() + FRAME_DURATION);
invalidateSelf();
}
};
}
public class ColorAnimationDrawable extends Drawable implements Animatable {
private static final long FRAME_DURATION = 1000 / 60;
private static final long ANIMATION_DURATION = 1500;
private static final int ACCCENT_COLOR = 0x33FFFFFF;
private static final int DIM_COLOR = 0x33000000;
private static final Random mRandom = new Random();
private final Paint mPaint = new Paint();
private boolean mIsRunning;
private int mStartColor;
private int mEndColor;
private int mCurrentColor;
private long mStartTime;
@Override
public void draw(Canvas canvas) {
final Rect bounds = getBounds();
mPaint.setColor(mCurrentColor);
canvas.drawRect(bounds, mPaint);
mPaint.setColor(ACCCENT_COLOR);
canvas.drawRect(bounds.left, bounds.top, bounds.right, bounds.top + 1, mPaint);
mPaint.setColor(DIM_COLOR);
canvas.drawRect(bounds.left, bounds.bottom - 2, bounds.right, bounds.bottom, mPaint);
}
@Override
public void setAlpha(int alpha) {
oops("setAlpha(int)");
}
@Override
public void setColorFilter(ColorFilter cf) {
oops("setColorFilter(ColorFilter)");
}
@Override
public int getOpacity() {
return PixelFormat.TRANSPARENT;
}
@Override
public void start() {
if (!isRunning()) {
mIsRunning = true;
mStartTime = AnimationUtils.currentAnimationTimeMillis();
mStartColor = randomColor();
mEndColor = randomColor();
scheduleSelf(mUpdater, SystemClock.uptimeMillis() + FRAME_DURATION);
invalidateSelf();
}
}
@Override
public void stop() {
if (isRunning()) {
unscheduleSelf(mUpdater);
mIsRunning = false;
}
}
@Override
public boolean isRunning() {
return mIsRunning;
}
private void oops(String message) {
throw new UnsupportedOperationException("ColorAnimationDrawable doesn't support " + message);
}
private static int randomColor() {
return mRandom.nextInt() & 0x00FFFFFF;
}
private static int evaluate(float fraction, int startValue, int endValue) {
return (int) (startValue + fraction * (endValue - startValue));
}
private final Runnable mUpdater = new Runnable() {
@Override
public void run() {
long now = AnimationUtils.currentAnimationTimeMillis();
long duration = now - mStartTime;
if (duration >= ANIMATION_DURATION) {
mStartColor = mEndColor;
mEndColor = randomColor();
mStartTime = now;
mCurrentColor = mStartColor;
} else {
float fraction = duration / (float) ANIMATION_DURATION;
//@formatter:off
mCurrentColor = Color.rgb(
evaluate(fraction, Color.red(mStartColor), Color.red(mEndColor)), // red
evaluate(fraction, Color.green(mStartColor), Color.green(mEndColor)), // green
evaluate(fraction, Color.blue(mStartColor), Color.blue(mEndColor))); // blue
//@formatter:on
}
scheduleSelf(mUpdater, SystemClock.uptimeMillis() + FRAME_DURATION);
invalidateSelf();
}
};
}
我認為唯一有趣的事情在這段代碼是使用的方法來激活一個顏色變化。它由提取每個顏色分量和動畫這些值,而不是整個顏色。
我申請這個可拉的我和boooom ActionBar是工作!我很驚訝,開始調查。在看AOSP源代碼果凍豆MR1釋放,我注意到,這一問題被固定由亞當·鮑威爾(一個工程師在谷歌工作的UI工具包)與a7cc06d。現在的代碼如下所述:
[java]
public void setPrimaryBackground(Drawable bg) { if (mBackground != null) { mBackground.setCallback(null); unscheduleDrawable(mBackground); } mBackground = bg; if (bg != null) { bg.setCallback(this); } setWillNotDraw(mIsSplit ? mSplitBackground == null : mBackground == null && mStackedBackground == null); invalidate();}
public void setPrimaryBackground(Drawable bg) { if (mBackground != null) { mBackground.setCallback(null); unscheduleDrawable(mBackground); } mBackground = bg; if (bg != null) { bg.setCallback(this); } setWillNotDraw(mIsSplit ? mSplitBackground == null : mBackground == null && mStackedBackground == null); invalidate();}
這個問題,這種修復是它不是用於預api 17構建。所以我想出了一個很簡單的解決辦法,為pre api 17:注冊一個自定義的繪圖。回調,使ActionBarContainer反復設置相同的繪圖與ActionBar的setBackgroundDrawable(繪圖)方法:
[java]
public class MainActivity extends Activity {
private final Handler mHandler = new Handler();
private ColorAnimationDrawable mActionBarBackground;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
mActionBarBackground = new ColorAnimationDrawable();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
mActionBarBackground.setCallback(mDrawableCallback);
} else {
getActionBar().setBackgroundDrawable(mActionBarBackground);
}
mActionBarBackground.start();
}
@Override
protected void onResume() {
super.onResume();
mActionBarBackground.start();
}
@Override
protected void onPause() {
super.onPause();
mActionBarBackground.stop();
}
private Drawable.Callback mDrawableCallback = new Drawable.Callback() {
@Override
public void invalidateDrawable(Drawable who) {
getActionBar().setBackgroundDrawable(who);
}
@Override
public void scheduleDrawable(Drawable who, Runnable what, long when) {
mHandler.postAtTime(what, when);
}
@Override
public void unscheduleDrawable(Drawable who, Runnable what) {
mHandler.removeCallbacks(what);
}
};
public class MainActivity extends Activity {
private final Handler mHandler = new Handler();
private ColorAnimationDrawable mActionBarBackground;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
mActionBarBackground = new ColorAnimationDrawable();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
mActionBarBackground.setCallback(mDrawableCallback);
} else {
getActionBar().setBackgroundDrawable(mActionBarBackground);
}
mActionBarBackground.start();
}
@Override
protected void onResume() {
super.onResume();
mActionBarBackground.start();
}
@Override
protected void onPause() {
super.onPause();
mActionBarBackground.stop();
}
private Drawable.Callback mDrawableCallback = new Drawable.Callback() {
@Override
public void invalidateDrawable(Drawable who) {
getActionBar().setBackgroundDrawable(who);
}
@Override
public void scheduleDrawable(Drawable who, Runnable what, long when) {
mHandler.postAtTime(what, when);
}
@Override
public void unscheduleDrawable(Drawable who, Runnable what) {
mHandler.removeCallbacks(what);
}
};
[java]
}
}
多虧了這個技巧,你現在可以激活你的背景ActionBar回到API 11但請記住這可能有幾個,有時嚴重的後果在你的應用程序:
它可以讓你的應用程序看起來不同和更加優美的特色是微小的,微妙的和漂亮的細節
當設置一個動畫背景一個ActionBar,總是確保盡可能是微妙的。動畫不應干擾或中斷用戶在他/她與你的應用程序的交互,比如你可以運行動畫只有當用戶不觸及你的活動。 使用本文中描述的技術力量系統失效整個ActionBarContainer對於每個動畫幀。減少你的動畫的持續時間盡可能多的CPU和GPU消費
動畫背景可拉的不應該是一些必要的程序。可拉的只能作為樣式組件而不是交互組件。
我可以寫一整本書的章可拉的概念。把簡單,當設置繪圖作為一個視圖的背景,視圖注冊自己是可拉的的回調。這讓繪圖視圖無效它屬於。換句話說,它允許您創建畫板,可以刷新/重畫自己。Android還將有專家說它讓你輕易洩露上下文保持靜態引用時一個繪圖。
1.Sn7326概述SN7326是一款帶智能自掃描的鍵盤擴展芯片,支持多達8*8個按鍵。按下/松開按鍵的動作被編碼成一個字節的數據存入到按鍵事件寄存器(key event
先上圖:這裡以添加 afinal_0.5.1_bin.jar 為例。第一步:添加jar包到libs裡面,系統自動把jar加載到android private librar
本文實例總結了 Android中Notification用法。分享給大家供大家參考,具體如下:我們在用手機的時候,如果來了短信,而我們沒有點擊查看的話,是不是在手機的最上
概括這篇博客裡面就來實踐下。在上一篇博客裡面說到了OkHttp類似HttpUrlConnection。按這樣說的話,我們在項目中肯定還是要封裝一層。如果嫌封裝麻煩的話,也