Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

Android Live Wallpaper

$
0
0

Android Live Wallpaper,这篇教程讲解android透明屏幕的实现方式。它以eclipse4.2、java 1.6、android4.1位基础。

1. 提前预习

  下面的教程假设您已经掌握了android开发的基本知识 Android developmentAndroid开发教程,学习基本知识,可以参考这个教程:http://www.vogella.com/tutorials/Android/article.html


2.概述 

2.1. Live Wallpapers

Live Wallpapers是为Android主屏幕提供动画的、交互式的背景。live墙纸与其他Android应用程序相似,可以使用大多数相同的功能。

2.2. 这样创建live wallpaper

要创建一个活墙纸,您需要创建一个描述您的墙纸的XML文件。这个文件应该包含应用程序的描述,并且可以包含一个预览和一个连接到一个允许自定义live墙纸的偏好活动活动的链接。

您还创建了一个必须扩展WallpaperService类的服务。这个类是系统中所有活墙纸的基类。您必须实现onCreateEngine()方法并返回一个android.service.wallpaper.WallpaperService.Engine类型的对象。这个对象处理生命周期事件、动画和墙纸的图画。引擎类定义了生命周期方法,例如onCreate()、onSurfaceCreated()、onVisibilityChanged()、onOffsetsChanged()、onTouchEvent()和onCommand()。

该服务需要允许使用android。权限。BIND_WALLPAPER注册,必须通过一个android.service.wallpaper意图过滤器。WallpaperService行动。

2.3. Intent to set the wallpaper

您可以使用意图来设置墙纸。

// Button to set the Wallpaper
public void onClick(View view) {
    Intent intent = new Intent(
            WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
    intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT,
        new ComponentName(this, MyWallpaperService.class));
    startActivity(intent);
}


3. Android Wallpaper 例子

创建一个名为de.vogella.android.wallpaper的新项目。不要创建Activity。

创建/ res/ xml文件夹并创建my墙纸的xml文件。

<?xml version="1.0" encoding="UTF-8"?>
<wallpaper
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:thumbnail="@drawable/icon"
    android:description="@string/wallpaper_description"
    android:settingsActivity="de.vogella.android.wallpaper.MyPreferencesActivity"/>

这个文件包含你的墙纸和预览图。您还可以输入一个活动的链接,该活动允许配置墙纸。这个资源文件将与androidmanifest . xml链接起来。您还可以包括“android:thumbnail属性”,它可以指向一个可绘制的,它可以提供一个较小的运行墙纸的图像。

改变你的AndroidManifest。xml到下面来定义您的MyWallpaperService服务。也定义uses-feature。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="de.vogella.android.wallpaper"
    android:versionCode="1"
    android:versionName="1.0" >

    <application
        android:icon="@drawable/icon"
        android:label="@string/app_name" >
        <service
            android:name="MyWallpaperService"
            android:enabled="true"
            android:label="Wallpaper Example "
            android:permission="android.permission.BIND_WALLPAPER" >
            <intent-filter>
                <action android:name="android.service.wallpaper.WallpaperService" >
                </action>
            </intent-filter>

            <meta-data
                android:name="android.service.wallpaper"
                android:resource="@xml/mywallpaper" >
            </meta-data>
        </service>

        <activity
            android:name=".MyPreferencesActivity"
            android:exported="true"
            android:label="@string/app_name"
            android:theme="@android:style/Theme.Light.WallpaperSettings" >
        </activity>
        <activity
            android:name=".SetWallpaperActivity"
            android:label="@string/app_name"
            android:theme="@android:style/Theme.Light.WallpaperSettings" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

    <uses-sdk android:minSdkVersion="10" />

    <uses-feature
        android:name="android.software.live_wallpaper"
        android:required="true" >
    </uses-feature>

</manifest>


我们创建MyPoint类来保存所绘制的元素。
package de.vogella.android.wallpaper;

public class MyPoint {
    String text;
    private int x;
    private int y;

    public MyPoint(String text, int x, int y) {
        this.text = text;
        this.x = x;
        this.y = y;
    }
}

创建一个新的activity,在 res/xml文件夹下创建prefs.xml文件。
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <CheckBoxPreference android:key="touch"
        android:title="Enable Touch"></CheckBoxPreference>
    <EditTextPreference android:key="numberOfCircles"
        android:title="Number of Circles"></EditTextPreference>
</PreferenceScreen>


创建一个名为mypreferencesactivity新activity和下面的类。
package de.vogella.android.wallpaper;

import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.PreferenceActivity;
import android.widget.Toast;

public class MyPreferencesActivity extends PreferenceActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.prefs);

        // add a validator to the "numberofCircles" preference so that it only
        // accepts numbers
        Preference circlePreference = getPreferenceScreen().findPreference(
                "numberOfCircles");

        // add the validator
        circlePreference.setOnPreferenceChangeListener(numberCheckListener);
    }

    /**
     * Checks that a preference is a valid numerical value
     */
    Preference.OnPreferenceChangeListener numberCheckListener = new OnPreferenceChangeListener() {

        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            // check that the string is an integer
            if (newValue != null && newValue.toString().length() > 0
                    && newValue.toString().matches("\\d*")) {
                return true;
            }
            // If now create a message to the user
            Toast.makeText(MyPreferencesActivity.this, "Invalid Input",
                    Toast.LENGTH_SHORT).show();
            return false;
        }
    };

}

创建一个Wallpaper 的服务

package de.vogella.android.wallpaper;

import java.util.ArrayList;
import java.util.List;

import android.content.SharedPreferences;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.service.wallpaper.WallpaperService;
import android.view.MotionEvent;
import android.view.SurfaceHolder;

public class MyWallpaperService extends WallpaperService {

    @Override
    public Engine onCreateEngine() {
        return new MyWallpaperEngine();
    }

    private class MyWallpaperEngine extends Engine {
        private final Handler handler = new Handler();
        private final Runnable drawRunner = new Runnable() {
            @Override
            public void run() {
                draw();
            }

        };
        private List<MyPoint> circles;
        private Paint paint = new Paint();
        private int width;
        int height;
        private boolean visible = true;
        private int maxNumber;
        private boolean touchEnabled;

        public MyWallpaperEngine() {
            SharedPreferences prefs = PreferenceManager
                    .getDefaultSharedPreferences(MyWallpaperService.this);
            maxNumber = Integer
                    .valueOf(prefs.getString("numberOfCircles", "4"));
            touchEnabled = prefs.getBoolean("touch", false);
            circles = new ArrayList<MyPoint>();
            paint.setAntiAlias(true);
            paint.setColor(Color.WHITE);
            paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeJoin(Paint.Join.ROUND);
            paint.setStrokeWidth(10f);
            handler.post(drawRunner);
        }

        @Override
        public void onVisibilityChanged(boolean visible) {
            this.visible = visible;
            if (visible) {
                handler.post(drawRunner);
            } else {
                handler.removeCallbacks(drawRunner);
            }
        }



}

@Override
        public void onSurfaceDestroyed(SurfaceHolder holder) {
            super.onSurfaceDestroyed(holder);
            this.visible = false;
            handler.removeCallbacks(drawRunner);
        }

        @Override
        public void onSurfaceChanged(SurfaceHolder holder, int format,
                int width, int height) {
            this.width = width;
            this.height = height;
            super.onSurfaceChanged(holder, format, width, height);
        }

        @Override
        public void onTouchEvent(MotionEvent event) {
            if (touchEnabled) {

                float x = event.getX();
                float y = event.getY();
                SurfaceHolder holder = getSurfaceHolder();
                Canvas canvas = null;
                try {
                    canvas = holder.lockCanvas();
                    if (canvas != null) {
                        canvas.drawColor(Color.BLACK);
                        circles.clear();
                        circles.add(new MyPoint(
                                String.valueOf(circles.size() + 1), x, y));
                        drawCircles(canvas, circles);

                    }
                } finally {
                    if (canvas != null)
                        holder.unlockCanvasAndPost(canvas);
                }
                super.onTouchEvent(event);
            }
        }

        private void draw() {
            SurfaceHolder holder = getSurfaceHolder();
            Canvas canvas = null;
            try {
                canvas = holder.lockCanvas();
                if (canvas != null) {
                    if (circles.size() >= maxNumber) {
                        circles.clear();
                    }
                    int x = (int) (width * Math.random());
                    int y = (int) (height * Math.random());
                    circles.add(new MyPoint(String.valueOf(circles.size() + 1),
                            x, y));
                    drawCircles(canvas, circles);
                }
            } finally {
                if (canvas != null)
                    holder.unlockCanvasAndPost(canvas);
            }
            handler.removeCallbacks(drawRunner);
            if (visible) {
                handler.postDelayed(drawRunner, 5000);
            }
        }

        // Surface view requires that all elements are drawn completely
        private void drawCircles(Canvas canvas, List<MyPoint> circles) {
            canvas.drawColor(Color.BLACK);
            for (MyPoint point : circles) {
                canvas.drawCircle(point.x, point.y, 20.0f, paint);
            }
        }
    }

创建下列activity,该activity应该使用包含一个按钮的布局。这个按钮应该使用onClick属性来指向onClick方法。

package de.vogella.android.wallpaper;

import android.app.Activity;
import android.app.WallpaperManager;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

public class SetWallpaperActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    public void onClick(View view) {
        Intent intent = new Intent(
                WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
        intent.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT,
                new ComponentName(this, MyWallpaperService.class));
        startActivity(intent);
    }
}
如果您开始应用程序,您的应用程序应该允许设置壁纸。你的背景应该类似下面的截图。如果您通过首选项启用了触摸功能,您可以单击屏幕来删除现有的圆圈,也可以通过设置来定义应该显示的圆圈的数量。



4.关于这个网站


vogella


作者:gsg8709 发表于2017/9/12 18:53:14 原文链接
阅读:17 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles