- 浏览: 1482012 次
文章分类
最新评论
-
sanrenxing_1:
GoEasy 实时推送支持IE6-IE11及大多数主流浏览器的 ...
WindowsPhone消息推送服务 -
yscyfy:
求 其源码 学习 ysc123@yeah.net
仿微信首次启动滑动界面效果
Android 自带Apps 学习---Live Wallpaper
1:配置Mainfest.xml
Android可查到该Live Wallpaper
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.wing.wallpaper.test" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="4" /> <!-- Android 会通过android.software.live_wallpaper feature Intent 获取动态壁纸列表 --> <uses-feature android:name="android.software.live_wallpaper" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".TestWallpaper" 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:label="@string/clock_settings" android:name="com.android.wallpaper.polarclock.PolarClockSettings" android:theme="@android:style/Theme" android:exported="true"> </activity> <!--android:permission="android.permission.BIND_WALLPAPER" 绑定壁纸权限 --> <!--<action android:name="android.service.wallpaper.WallpaperService" 动态壁纸主View Layout --> <!-- <meta-data android:name="android.service.wallpaper" android:resource="@xml/polar_clock" /> Wallpaper 相关配置 --> <service android:label="@string/wallpaper_clock" android:name="com.android.wallpaper.polarclock.PolarClockWallpaper" android:permission="android.permission.BIND_WALLPAPER"> <intent-filter> <action android:name="android.service.wallpaper.WallpaperService" /> </intent-filter> <meta-data android:name="android.service.wallpaper" android:resource="@xml/polar_clock" /> </service> </application> </manifest>
Wallpaper 相关配置xml/polar_clock.xml
<wallpaper xmlns:android="http://schemas.android.com/apk/res/android" android:author="@string/wallpaper_clock_author" android:description="@string/wallpaper_clock_desc" android:thumbnail="@drawable/polarclock_thumb" android:settingsActivity="com.android.wallpaper.polarclock.PolarClockSettings" />
Wallpaper 作者,缩略图,设置Activity
2: 创建Setting Activity
public class PolarClockSettings extends WallpaperSettingsActivity implements SharedPreferences.OnSharedPreferenceChangeListener { @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); //定义SharedPreferencesName,可通过该Name对其修改时间注册监听,见下 getPreferenceManager().setSharedPreferencesName( PolarClockWallpaper.SHARED_PREFS_NAME); addPreferencesFromResource(R.xml.polar_clock_prefs); getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener( this); } @Override protected void onResume() { super.onResume(); } @Override protected void onDestroy() { getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener( this); super.onDestroy(); } public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { (new BackupManager(this)).dataChanged(); } }
Setting Activity 配置 xml/R.xml.polar_clock_prefs
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:title="@string/clock_settings" android:key="polar_clock_settings"> <CheckBoxPreference android:key="show_seconds" android:title="@string/show_seconds" android:defaultValue="true" android:persistent="true" /> <CheckBoxPreference android:key="variable_line_width" android:title="@string/variable_line_width" android:defaultValue="true" android:persistent="true" /> <ListPreference android:key="palette" android:title="@string/palette" android:entries="@array/polar_clock_palette_names" android:entryValues="@array/polar_clock_palette_ids" /> </PreferenceScreen>
3: Wallpaper 主View
public class PolarClockWallpaper extends WallpaperService { private final Handler mHandler = new Handler(); private IntentFilter mFilter; @Override public void onCreate() { super.onCreate(); mFilter = new IntentFilter(); mFilter.addAction(Intent.ACTION_TIMEZONE_CHANGED); } @Override public void onDestroy() { super.onDestroy(); } public Engine onCreateEngine() { return new ClockEngine(); }
class ClockEngine extends Engine implements SharedPreferences.OnSharedPreferenceChangeListener { private static final float SMALL_RING_THICKNESS = 8.0f; private static final float MEDIUM_RING_THICKNESS = 16.0f; private static final float LARGE_RING_THICKNESS = 32.0f; private static final float DEFAULT_RING_THICKNESS = 24.0f; private static final float SMALL_GAP = 14.0f; private static final float LARGE_GAP = 38.0f; private final HashMap<String, ClockPalette> mPalettes = new HashMap<String, ClockPalette>(); private ClockPalette mPalette; private SharedPreferences mPrefs; private boolean mShowSeconds; private boolean mVariableLineWidth; private boolean mWatcherRegistered; private Time mCalendar; private final Paint mPaint = new Paint(); private final RectF mRect = new RectF(); private float mOffsetX; private final BroadcastReceiver mWatcher = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { final String timeZone = intent.getStringExtra("time-zone"); mCalendar = new Time(TimeZone.getTimeZone(timeZone).getID()); drawFrame(); } }; private final Runnable mDrawClock = new Runnable() { public void run() { drawFrame(); } }; private boolean mVisible; ClockEngine() { //android 自带xml解析工具 XmlResourceParser xrp = getResources().getXml(R.xml.polar_clock_palettes); try { int what = xrp.getEventType(); while (what != END_DOCUMENT) { if (what == START_TAG) { if ("palette".equals(xrp.getName())) { ClockPalette pal = ClockPalette.parseXmlPaletteTag(xrp); if (pal.getId() != null) { mPalettes.put(pal.getId(), pal); } } } what = xrp.next(); } } catch (IOException e) { Log.e(LOG_TAG, "An error occured during wallpaper configuration:", e); } catch (XmlPullParserException e) { Log.e(LOG_TAG, "An error occured during wallpaper configuration:", e); } finally { xrp.close(); } mPalette = CyclingClockPalette.getFallback(); } @Override public void onCreate(SurfaceHolder surfaceHolder) { super.onCreate(surfaceHolder); //对setting的SharedPreferences 注册修改监听 mPrefs = PolarClockWallpaper.this.getSharedPreferences(SHARED_PREFS_NAME, 0); mPrefs.registerOnSharedPreferenceChangeListener(this); // load up user's settings 加载SharedPreferences onSharedPreferenceChanged(mPrefs, null); mCalendar = new Time(); mCalendar.setToNow(); final Paint paint = mPaint; paint.setAntiAlias(true); paint.setStrokeWidth(DEFAULT_RING_THICKNESS); paint.setStrokeCap(Paint.Cap.ROUND); paint.setStyle(Paint.Style.STROKE); if (isPreview()) { mOffsetX = 0.5f; } } @Override public void onDestroy() { super.onDestroy(); //取消对时区改变的坚挺 if (mWatcherRegistered) { mWatcherRegistered = false; unregisterReceiver(mWatcher); } //取消图像重绘事件队列 mHandler.removeCallbacks(mDrawClock); } //特定SharedPreferences 配置改变回调方法 public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { boolean changed = false; if (key == null || PREF_SHOW_SECONDS.equals(key)) { mShowSeconds = sharedPreferences.getBoolean( PREF_SHOW_SECONDS, true); changed = true; } if (key == null || PREF_VARIABLE_LINE_WIDTH.equals(key)) { mVariableLineWidth = sharedPreferences.getBoolean( PREF_VARIABLE_LINE_WIDTH, true); changed = true; } if (key == null || PREF_PALETTE.equals(key)) { String paletteId = sharedPreferences.getString( PREF_PALETTE, ""); ClockPalette pal = mPalettes.get(paletteId); if (pal != null) { mPalette = pal; changed = true; } } if (mVisible && changed) { drawFrame(); } } //View 是否可见变化响应时间 @Override public void onVisibilityChanged(boolean visible) { mVisible = visible; if (visible) { if (!mWatcherRegistered) { mWatcherRegistered = true; registerReceiver(mWatcher, mFilter, null, mHandler); } mCalendar = new Time(); mCalendar.setToNow(); } else { if (mWatcherRegistered) { mWatcherRegistered = false; unregisterReceiver(mWatcher); } mHandler.removeCallbacks(mDrawClock); } drawFrame(); } //View 大小发生改变 @Override public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) { super.onSurfaceChanged(holder, format, width, height); drawFrame(); } @Override public void onSurfaceCreated(SurfaceHolder holder) { super.onSurfaceCreated(holder); } @Override public void onSurfaceDestroyed(SurfaceHolder holder) { super.onSurfaceDestroyed(holder); mVisible = false; mHandler.removeCallbacks(mDrawClock); } //位置改变,如Home滑动到别的页,3->1->3 @Override public void onOffsetsChanged(float xOffset, float yOffset, float xStep, float yStep, int xPixels, int yPixels) { if (isPreview()) return; mOffsetX = xOffset; drawFrame(); } //绘制view void drawFrame() { if (mPalette == null) { Log.w("PolarClockWallpaper", "no palette?!"); return; } final SurfaceHolder holder = getSurfaceHolder(); final Rect frame = holder.getSurfaceFrame(); final int width = frame.width(); final int height = frame.height(); Canvas c = null; try { c = holder.lockCanvas(); if (c != null) { final Time calendar = mCalendar; final Paint paint = mPaint; final long millis = System.currentTimeMillis(); calendar.set(millis); calendar.normalize(false); int s = width / 2; int t = height / 2; c.drawColor(mPalette.getBackgroundColor()); c.translate(s + MathUtils.lerp(s, -s, mOffsetX), t); c.rotate(-90.0f); if (height < width) { c.scale(0.9f, 0.9f); } float size = Math.min(width, height) * 0.5f - DEFAULT_RING_THICKNESS; final RectF rect = mRect; rect.set(-size, -size, size, size); float angle; float lastRingThickness = DEFAULT_RING_THICKNESS; if (mShowSeconds) { // Draw seconds angle = (float) (millis % 60000) / 60000.0f; //Log.d("PolarClock", "millis=" + millis + ", angle=" + angle); paint.setColor(mPalette.getSecondColor(angle)); if (mVariableLineWidth) { lastRingThickness = SMALL_RING_THICKNESS; paint.setStrokeWidth(lastRingThickness); } c.drawArc(rect, 0.0f, angle * 360.0f, false, paint); } // Draw minutes size -= (SMALL_GAP + lastRingThickness); rect.set(-size, -size, size, size); angle = ((calendar.minute * 60.0f + calendar.second) % 3600) / 3600.0f; paint.setColor(mPalette.getMinuteColor(angle)); if (mVariableLineWidth) { lastRingThickness = MEDIUM_RING_THICKNESS; paint.setStrokeWidth(lastRingThickness); } c.drawArc(rect, 0.0f, angle * 360.0f, false, paint); // Draw hours size -= (SMALL_GAP + lastRingThickness); rect.set(-size, -size, size, size); angle = ((calendar.hour * 60.0f + calendar.minute) % 1440) / 1440.0f; paint.setColor(mPalette.getHourColor(angle)); if (mVariableLineWidth) { lastRingThickness = LARGE_RING_THICKNESS; paint.setStrokeWidth(lastRingThickness); } c.drawArc(rect, 0.0f, angle * 360.0f, false, paint); // Draw day size -= (LARGE_GAP + lastRingThickness); rect.set(-size, -size, size, size); angle = (calendar.monthDay - 1) / (float) (calendar.getActualMaximum(Time.MONTH_DAY) - 1); paint.setColor(mPalette.getDayColor(angle)); if (mVariableLineWidth) { lastRingThickness = MEDIUM_RING_THICKNESS; paint.setStrokeWidth(lastRingThickness); } c.drawArc(rect, 0.0f, angle * 360.0f, false, paint); // Draw month size -= (SMALL_GAP + lastRingThickness); rect.set(-size, -size, size, size); angle = (calendar.month) / 11.0f; // NB: month is already on [0..11] paint.setColor(mPalette.getMonthColor(angle)); if (mVariableLineWidth) { lastRingThickness = LARGE_RING_THICKNESS; paint.setStrokeWidth(lastRingThickness); } c.drawArc(rect, 0.0f, angle * 360.0f, false, paint); } } finally { if (c != null) holder.unlockCanvasAndPost(c); } mHandler.removeCallbacks(mDrawClock); if (mVisible) { if (mShowSeconds) { mHandler.postDelayed(mDrawClock, 1000 / 25); } else { // If we aren't showing seconds, we don't need to update // nearly as often. mHandler.postDelayed(mDrawClock, 2000); } } } }
其他相关类
// Clock 父类 static abstract class ClockPalette { public static ClockPalette parseXmlPaletteTag(XmlResourceParser xrp) { String kind = xrp.getAttributeValue(null, "kind"); if ("cycling".equals(kind)) { return CyclingClockPalette.parseXmlPaletteTag(xrp); } else { return FixedClockPalette.parseXmlPaletteTag(xrp); } } public abstract int getBackgroundColor(); // forAngle should be on [0.0,1.0) but 1.0 must be tolerated public abstract int getSecondColor(float forAngle); public abstract int getMinuteColor(float forAngle); public abstract int getHourColor(float forAngle); public abstract int getDayColor(float forAngle); public abstract int getMonthColor(float forAngle); public abstract String getId(); } static class FixedClockPalette extends ClockPalette { protected String mId; protected int mBackgroundColor; protected int mSecondColor; protected int mMinuteColor; protected int mHourColor; protected int mDayColor; protected int mMonthColor; private static FixedClockPalette sFallbackPalette = null; public static FixedClockPalette getFallback() { if (sFallbackPalette == null) { sFallbackPalette = new FixedClockPalette(); sFallbackPalette.mId = "default"; sFallbackPalette.mBackgroundColor = Color.WHITE; sFallbackPalette.mSecondColor = sFallbackPalette.mMinuteColor = sFallbackPalette.mHourColor = sFallbackPalette.mDayColor = sFallbackPalette.mMonthColor = Color.BLACK; } return sFallbackPalette; } private FixedClockPalette() { } public static ClockPalette parseXmlPaletteTag(XmlResourceParser xrp) { final FixedClockPalette pal = new FixedClockPalette(); pal.mId = xrp.getAttributeValue(null, "id"); String val; if ((val = xrp.getAttributeValue(null, "background")) != null) pal.mBackgroundColor = Color.parseColor(val); if ((val = xrp.getAttributeValue(null, "second")) != null) pal.mSecondColor = Color.parseColor(val); if ((val = xrp.getAttributeValue(null, "minute")) != null) pal.mMinuteColor = Color.parseColor(val); if ((val = xrp.getAttributeValue(null, "hour")) != null) pal.mHourColor = Color.parseColor(val); if ((val = xrp.getAttributeValue(null, "day")) != null) pal.mDayColor = Color.parseColor(val); if ((val = xrp.getAttributeValue(null, "month")) != null) pal.mMonthColor = Color.parseColor(val); return (pal.mId == null) ? null : pal; } @Override public int getBackgroundColor() { return mBackgroundColor; } @Override public int getSecondColor(float forAngle) { return mSecondColor; } @Override public int getMinuteColor(float forAngle) { return mMinuteColor; } @Override public int getHourColor(float forAngle) { return mHourColor; } @Override public int getDayColor(float forAngle) { return mDayColor; } @Override public int getMonthColor(float forAngle) { return mMonthColor; } @Override public String getId() { return mId; } } static class CyclingClockPalette extends ClockPalette { protected String mId; protected int mBackgroundColor; protected float mSaturation; protected float mBrightness; private static final int COLORS_CACHE_COUNT = 720; private final int[] mColors = new int[COLORS_CACHE_COUNT]; private static CyclingClockPalette sFallbackPalette = null; public static CyclingClockPalette getFallback() { if (sFallbackPalette == null) { sFallbackPalette = new CyclingClockPalette(); sFallbackPalette.mId = "default_c"; sFallbackPalette.mBackgroundColor = Color.WHITE; sFallbackPalette.mSaturation = 0.8f; sFallbackPalette.mBrightness = 0.9f; sFallbackPalette.computeIntermediateColors(); } return sFallbackPalette; } private CyclingClockPalette() { } private void computeIntermediateColors() { final int[] colors = mColors; final int count = colors.length; float invCount = 1.0f / (float) COLORS_CACHE_COUNT; for (int i = 0; i < count; i++) { colors[i] = Color.HSBtoColor(i * invCount, mSaturation, mBrightness); } } public static ClockPalette parseXmlPaletteTag(XmlResourceParser xrp) { final CyclingClockPalette pal = new CyclingClockPalette(); pal.mId = xrp.getAttributeValue(null, "id"); String val; if ((val = xrp.getAttributeValue(null, "background")) != null) pal.mBackgroundColor = Color.parseColor(val); if ((val = xrp.getAttributeValue(null, "saturation")) != null) pal.mSaturation = Float.parseFloat(val); if ((val = xrp.getAttributeValue(null, "brightness")) != null) pal.mBrightness = Float.parseFloat(val); if (pal.mId == null) { return null; } else { pal.computeIntermediateColors(); return pal; } } @Override public int getBackgroundColor() { return mBackgroundColor; } @Override public int getSecondColor(float forAngle) { if (forAngle >= 1.0f || forAngle < 0.0f) forAngle = 0.0f; return mColors[((int) (forAngle * COLORS_CACHE_COUNT))]; } @Override public int getMinuteColor(float forAngle) { if (forAngle >= 1.0f || forAngle < 0.0f) forAngle = 0.0f; return mColors[((int) (forAngle * COLORS_CACHE_COUNT))]; } @Override public int getHourColor(float forAngle) { if (forAngle >= 1.0f || forAngle < 0.0f) forAngle = 0.0f; return mColors[((int) (forAngle * COLORS_CACHE_COUNT))]; } @Override public int getDayColor(float forAngle) { if (forAngle >= 1.0f || forAngle < 0.0f) forAngle = 0.0f; return mColors[((int) (forAngle * COLORS_CACHE_COUNT))]; } @Override public int getMonthColor(float forAngle) { if (forAngle >= 1.0f || forAngle < 0.0f) forAngle = 0.0f; return mColors[((int) (forAngle * COLORS_CACHE_COUNT))]; } @Override public String getId() { return mId; } }
配置ClockDelete 的xml
/xml/polar_clock_palettes
<?xml version="1.0" encoding="utf-8"?> <palettes> <!-- basic white polar clock with color-cycling rings --> <palette kind="cycling" id="palette_white_c" background="#FFFFFFFF" saturation="0.8" brightness="0.9" /> <!-- same as above, but on black --> <palette kind="cycling" id="palette_black_c" background="#FF000000" saturation="1.0" brightness="0" /> <!-- a nice gray color scheme with an orange seconds ring --> <palette kind="fixed" id="palette_gray" background="#FF555555" second="#FFCC8800" minute="#FF333333" hour="#FF000000" day="#FF999999" month="#FF777777" /> <!-- smooth black with a purple cast --> <palette kind="fixed" id="palette_violet" background="#FF181020" second="#FF602070" minute="#603050" hour="#FF040008" day="#FF706080" month="#FF403050" /> <!-- green on black --> <palette kind="fixed" id="palette_matrix" background="#FF002200" second="#FF00FF00" minute="#FF00BB00" hour="#FF007700" day="#FF00AA00" month="#FF006600" /> <!-- orange --> <palette kind="fixed" id="palette_halloween" background="#FF884400" second="#FFFFFF00" minute="#FFFF8800" hour="#FFFF8800" day="#FF000000" month="#FF000000" /> <!-- based on Zenburn by Jani Nurminen --> <palette kind="fixed" id="palette_zenburn" background="#FF3f3f3f" second="#FF8aCCCF" minute="#FFCB9292" hour="#FFCCDC90" day="#FFDCA3A3" month="#FF7f9f7f" /> <!-- electric blue --> <palette kind="fixed" id="palette_oceanic" background="#FF000066" second="#FF6666FF" minute="#FF0000FF" hour="#FF0000AA" day="#FF000033" month="#FF000011" /> </palettes>
相关推荐
LiveWallpaper Live Wallpaper App using OpenGL ES 2.0
两个Android 动态壁纸 Live Wallpaper-WallpaperService
android系统自带的wallpaper例子,有高人将其分离 android系统自带的wallpaper例子,有高人将其分离
android-live-wallpaper 教你怎么写动态壁纸 博文链接:https://gundumw100.iteye.com/blog/904176
android动态桌面的创建教程。有兴趣的朋友可拿来参考一下。
动态壁纸的制作
Wallpaper 透明屏幕
Android 仿火萤视频桌面 神奇的LiveWallPaper
fantastic-android-animation A collection of Android animation repos background image taken from http://android-foundry.com/wallpaper-ice-cream-month/ Posts Framework UI View Menu Transition Pager/...
Android 动态壁纸 Live Wallpaper 工程 源代码
允许您选择视频作为墙纸的Android应用。 需要GLESv2或更高版本的支持来裁剪视频大小。 注意 这与大多数教程中所说的“构建一个安卓视频墙纸”不同,它不是一个演示,只是创建了一个以WallpaperSurface为目的地的...
Android Demos ...Livewallpaper/switch_animation Livewallpaper/switch_leftright MapApiV2Demo MultipleContacts OptionalDependencies PinchZoomDetector simperAudioStreamer sms TabHostExample ...
To showcase the different possibilities of this library I've created a demo 'Wallpaper Application'. You can find the source for this application in the ps-app/ folder. In case you want to install the...
桌面插件 Ditalix Live Wallpaper Suite 1.2.3.10-华丽动态壁纸集合 ICON:软件icon 软件名称:Ditalix Live Wallpaper Suite 软件版本:1.2.3.10~华丽动态壁纸集合 软件大小:31.27M 软件语言:英文 支持平台:...
com.fengqin.livewallpaper.sxpp-1.1-2-257704.apk
com.fengqin.livewallpaper.wh-1.1-2-257710.apk
Scroid (standing for Screen Android) is a wallpaper application for the Android platform. It consumes a REST based webservice which also will be released as open source in a different project. ...
wallpaper-cli, 获取或者设置桌面壁纸 墙纸 获取或者设置桌面壁纸在 macOS,Linux和 Windows 上工作。安装$ npm install --global wallpaper-cli用法$ wallpaper --help
快速课程,学习如何使用翻新,GSON,Realm,ButterKnife,Glide构建漂亮的Wallpaper Android应用 我们的应用程序是什么样的? 要求 您应该了解基本的Java编程语言 您应该对Android有一些经验(本课程不适用于Android...
Unobstrusive Android live wallpaper showing slowly moving wave lines. You may choose a theme, build your own, change if the lines should change width or have a uniform width, if they swing in harmony...