当前位置:首页 > 安卓源码 > 技术博客 >

Android创建自己的动态壁纸教程

时间:2018-08-09 15:45 来源:互联网 作者:源码搜藏 浏览: 收藏 挑错 推荐 打印

我在这篇文章中将描述我如何整理动态壁纸。 要创建动态壁纸,您需要设置以下内容 一个扩展 WallpaperService 并进一步实现扩展 Engine 类 的嵌套类的 类。 该类负责调用绘图代码。 显示壁纸设置列表的活动。(可选)。 在这里,我发现了Android Preference A

我在这篇文章中将描述我如何整理动态壁纸。

Android创建自己的动态壁纸教程Android创建自己的动态壁纸教程Android创建自己的动态壁纸教程

要创建动态壁纸,您需要设置以下内容

  1. 一个扩展WallpaperService 并进一步实现扩展Engine 的嵌套类的类。该类负责调用绘图代码。
  2. 显示壁纸设置列表的活动。(可选)。在这里,我发现了Android Preference API,它可以轻松地为应用程序创建设置
  3. xml 文件夹中壁纸的XML定义
  4. 用于动态壁纸和偏好活动的AndroidManifest.xml条目。

入门

1.要创建动态壁纸,您必须在课程类中WallpaperService找到有关课程的更多信息,访问https://developer.android.com/reference/android/service/wallpaper/WallpaperService.html

该类必须覆盖onCreateEngine()返回Engine 对象的  方法方法

此外,此类必须具有扩展Engine 的嵌套类。(我不知道为什么)

要创建下降动画,我需要连续绘制表面。之前在使用canvas视图invalidate() 方法时调用了更新视图。但是在Engine课堂上没有这样的方法。要首先绘制效果,您需要从中获取画布getSurfaceHolder();

之后,以特定间隔运行线程以更新绘图表面。

以下是动态skeleton壁纸类。

package matrixlw.app.skd.wa;

import android.content.Context;
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.util.Log;
import android.view.SurfaceHolder;

import com.enrico.colorpicker.colorDialog;

import java.util.Random;

/**
 * Created by sapan on 1/10/2017.
 */

public class matrixWall extends WallpaperService {

    private boolean mVisible;  // visible flag
    Canvas canvas;      // canvas reference
    int Drawspeed=10;   // thread call delay time
    Context mcontext;   //reference to the current context

   

    @Override
    public Engine onCreateEngine() {
        //set the Preference default value
        mcontext = this;  //set the current context
        
        //return the Engine Class
        return new LiveWall(); // this calls contain the wallpaper code
    }


    /*
    * this class extends the engine for the live wallpaper
    * THis class implements all the draw calls required to draw the wallpaper
    * This call is to neseted inside the wallpaper service class to function properly
    * don't know why though :(
     */
    public class LiveWall extends Engine
    {

        final Handler mHandler = new Handler(); // this is to handle the thread

        //the tread responsibe for drawing this thread get calls every time
        // drawspeed vars set the execution speed
        private final Runnable mDrawFrame = new Runnable() {
            public void run() {

              
                // This method get called each time to drwaw thw frame
                // Engine class does not provide any invlidate methods
                // as used in canvas
                // set your draw call here
                drawFrame();
            }
        };


        //Called when the surface is created
        @Override
        public void onSurfaceCreated(SurfaceHolder holder) {
            super.onSurfaceCreated(holder);

            //call the draw method
            // this is where you must call your draw code
            drawFrame();

        }

        // remove thread
        @Override
        public void onDestroy() {
            super.onDestroy();
            mHandler.removeCallbacks(mDrawFrame);
        }


        //called when varaible changed
        @Override
        public void onVisibilityChanged(boolean visible) {
            mVisible = visible;
            if (visible) {
              
    //call the drawFunction
                drawFrame();   
    
            } else {
                
                //this is necessay to remove the call back
                mHandler.removeCallbacks(mDrawFrame);
            }
        }

        //called when surface destroyed
        @Override
        public void onSurfaceDestroyed(SurfaceHolder holder) {
            super.onSurfaceDestroyed(holder);
            mVisible = false;
            //this is necessay to remove the call back
            mHandler.removeCallbacks(mDrawFrame);
        }



  // my function which contain the code to draw
        //this function contain the the main draw call
        /// this function need to call every time the code is executed
        // the thread call this functioin with some delay "drawspeed"
        public void drawFrame()
        {
            //getting the surface holder
            final SurfaceHolder holder = getSurfaceHolder();

            canvas = null;  // canvas
            try {
                canvas = holder.lockCanvas();  //get the canvas
                if (canvas != null) {
                    // draw something
     // my draw code
                  
                }
            } finally {
                if (canvas != null)
                    holder.unlockCanvasAndPost(canvas);
            }

            // Reschedule the next redraw
            // this is the replacement for the invilidate funtion
            // every time call the drawFrame to draw the matrix
            mHandler.removeCallbacks(mDrawFrame);
            if (mVisible) {
                // set the execution delay
                mHandler.postDelayed(mDrawFrame, Drawspeed);
            }
        }

        @Override
        public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            super.onSurfaceChanged(holder, format, width, height);
           // update when surface changed

        }
    }


}

2.创建xml定义。

作为壁纸服务,必须在mywallpaper.xml等xml文件夹中创建xml文件

Android创建自己的动态壁纸教程
<?xml version="1.0" encoding="UTF-8"?>
<wallpaper

    xmlns:android="http://schemas.android.com/apk/res/android"

    android:thumbnail="@mipmap/ic_launcher"



    android:settingsActivity="matrixlw.app.skd.wa.SettingsActivity"/>

这里android:settingsActivity="matrixlw.app.skd.wa.SettingsActivity"/> 指向在动态壁纸预览屏幕上单击设置按钮时调用的设置活动

3. 必须正确设置android AndroidManifest.xml 以获取运行此文件的动态壁纸。

  1. 设置功能
    <uses-feature android:name="android.software.live_wallpaper" />
  2. 添加壁纸和资源xml文件的服务。
    <service
                android:name=".matrixWall"
                android:enabled="true"
                android:label="MATRIX RAIN"
                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/mywallpaper"></meta-data>
            </service>
  3. 添加设置活动
    <activity
             android:name=".SettingsActivity"
             android:label="@string/title_activity_settings"
             android:exported="true">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
    
             </intent-filter>
    
         </activity>
    

    android:exported="true" 必须设置此处,否则单击设置按钮时将不会打开此活动

3.创建设置活动

“设置”活动包含用于自定义动态壁纸属性的UI。首选项活动是使用android首选项API创建的,这提供了一种创建首选项API的简便方法

有关详细信息,请访问:https//developer.android.com/guide/topics/ui/settings.html

Color Picker是使用richocid创建的库

参考:https//github.com/enricocid/Color-picker-library

我正在跳过设置活动。设置活动的文件和布局是SettingsActivity.java和xml / preferences。

4.整理动态壁纸:

矩阵雨效应将是我在我之前的文章中解释过的动态壁纸。

ref - 下面是该项目的抽奖代码

// ======== MATRIX LIVE WALLPAPER VARS
    int background_color= Color.parseColor("#FF000000");
    int text_color=Color.parseColor("#FF8BFF4A");

    int width = 1000000; //default initial width
    int height = 100; //default initial height
    int fontSize = 15; //font size of the text which will fall
    int columnSize = width/fontSize; //column size ; no of digit required to fill the screen
    int parentWidth;
    String text = "MATRIXRAIN";  // Text which need to be drawn
    char[] textChar = text.toCharArray(); // split the character of the text
    int textLength = textChar.length;   //length of the length text
    Random rand = new Random(); //random generater

    int[]  textPosition; // contain the position which will help to draw the text
    //======================

  //old matrix effect code
    void drawText()
    {
        //Set up the paint
        Paint paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(text_color);
        paint.setTextSize(15);


        //loop and paint
        for(int i =0 ;i<textPosition.length;i++)
        {
            // draw the text at the random position
            canvas.drawText(""+textChar[rand.nextInt(textLength)+0],i*fontSize,textPosition[i]*fontSize,paint);
            // check if text has reached bottom or not
            if(textPosition[i]*fontSize > height && Math.random() > 0.975)
                textPosition[i] = 0;   // change text position to zero when 0 when text is at the bottom

            textPosition[i]++; //increment the position array
        }
    }

    //old martix effect code
    public void canvasDraw()
    {
        Log.d("canvas ","drawing");
        //set the paint for the canvas
        Paint paint = new Paint();
        paint.setColor(background_color);

        paint.setAlpha(5);
        paint.setStyle(Paint.Style.FILL);
        canvas.drawRect(0, 0, width, height, paint);//draw rect to clear the canvas

        drawText(); // draw the canvas

    }

现在上面的代码需要插入到骨架壁纸服务代码中。在skeleton类中,DrawFrame()方法用于调用draw语句。

package matrixlw.app.skd.wa;

import android.content.Context;
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.util.Log;
import android.view.SurfaceHolder;

import com.enrico.colorpicker.colorDialog;

import java.util.Random;

/**
 * Created by sapan on 1/10/2017.
 */

public class matrixWall extends WallpaperService {

    private boolean mVisible;  // visible flag
    Canvas canvas;      // canvas reference
    int Drawspeed=10;   // thread call delay time
    Context mcontext;   //reference to the current context

    // ======== MATRIX LIVE WALLPAPER VARS
    int background_color= Color.parseColor("#FF000000");
    int text_color=Color.parseColor("#FF8BFF4A");

    int width = 1000000; //default initial width
    int height = 100; //default initial height
    int fontSize = 15; //font size of the text which will fall
    int columnSize = width/fontSize; //column size ; no of digit required to fill the screen
    int parentWidth;
    String text = "MATRIXRAIN";  // Text which need to be drawn
    char[] textChar = text.toCharArray(); // split the character of the text
    int textLength = textChar.length;   //length of the length text
    Random rand = new Random(); //random generater

    int[]  textPosition; // contain the position which will help to draw the text
    //======================

    @Override
    public Engine onCreateEngine() {
        //set the Preference default value
        mcontext = this;  //set the current context

        //Initalise and read the preference
        PreferenceManager.setDefaultValues(this, R.xml.preferences, false);

        SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
        text = sharedPref.getString("matrix_scroll_text", "MATRIX");
        Drawspeed = Integer.parseInt(sharedPref.getString("matrix_falling_speed","10"));
        fontSize = Integer.parseInt(sharedPref.getString("matrix_font_size","15"));
        background_color = colorDialog.getPickerColor(getBaseContext(), 1);
        text_color =colorDialog.getPickerColor(getBaseContext(), 2);

        //Some loggers Commnet or remove if you want
        Log.d("back_color",""+background_color);
        Log.d("text_color",""+text_color);

        textChar = text.toCharArray(); // split the character of the text
        textLength = textChar.length;
        columnSize = width/fontSize;

        //return the Engine Class
        return new LiveWall(); // this calls contain the wallpaper code
    }


    /*
    * this class extends the engine for the live wallpaper
    * THis class implements all the draw calls required to draw the wallpaper
    * This call is to neseted inside the wallpaper service class to function properly
    * don't know why though :(
     */
    public class LiveWall extends Engine
    {

        final Handler mHandler = new Handler(); // this is to handle the thread

        //the tread responsibe for drawing this thread get calls every time
        // drawspeed vars set the execution speed
        private final Runnable mDrawFrame = new Runnable() {
            public void run() {

                //Matrix code to the color when changed
                // callback can also be used but I havent
                background_color = colorDialog.getPickerColor(getBaseContext(), 1);
                text_color =colorDialog.getPickerColor(getBaseContext(), 2);
                // ^^^^^^^^

                // This method get called each time to drwaw thw frame
                // Engine class does not provide any invlidate methods
                // as used in canvas
                // set your draw call here
                drawFrame();
            }
        };


        //Called when the surface is created
        @Override
        public void onSurfaceCreated(SurfaceHolder holder) {
            super.onSurfaceCreated(holder);

            //update  the matrix variables
            width = getDesiredMinimumWidth();
            height = getDesiredMinimumHeight();
            columnSize = width/fontSize;
            //initalise the textposiotn to zero
            textPosition = new int[columnSize+1]; //add one more drop
            for(int x = 0; x < columnSize; x++) {
                textPosition[x] = 1;
            }
            //^^^^^^^^^^^^^^^

            //call the draw method
            // this is where you must call your draw code
            drawFrame();

        }

        // remove thread
        @Override
        public void onDestroy() {
            super.onDestroy();
            mHandler.removeCallbacks(mDrawFrame);
        }


        //called when varaible changed
        @Override
        public void onVisibilityChanged(boolean visible) {
            mVisible = visible;
            if (visible) {
                SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(mcontext);
                text = sharedPref.getString("matrix_scroll_text", "MATRIX");
                Drawspeed = Integer.parseInt(sharedPref.getString("matrix_falling_speed","10"));
                fontSize = Integer.parseInt(sharedPref.getString("matrix_font_size","15"));
                background_color = colorDialog.getPickerColor(getBaseContext(), 1);
                text_color =colorDialog.getPickerColor(getBaseContext(), 2);



                textChar = text.toCharArray(); // split the character of the text
                textLength = textChar.length;
                columnSize = width/fontSize;
                drawFrame();
            } else {
                SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(mcontext);
                text = sharedPref.getString("matrix_scroll_text", "MATRIX");
                Drawspeed = Integer.parseInt(sharedPref.getString("matrix_falling_speed","10"));
                fontSize = Integer.parseInt(sharedPref.getString("matrix_font_size","15"));
                background_color = colorDialog.getPickerColor(getBaseContext(), 1);
                text_color =colorDialog.getPickerColor(getBaseContext(), 2);



                textChar = text.toCharArray(); // split the character of the text
                textLength = textChar.length;
                columnSize = width/fontSize;

                //this is necessay to remove the call back
                mHandler.removeCallbacks(mDrawFrame);
            }
        }

        //called when surface destroyed
        @Override
        public void onSurfaceDestroyed(SurfaceHolder holder) {
            super.onSurfaceDestroyed(holder);
            mVisible = false;
            //this is necessay to remove the call back
            mHandler.removeCallbacks(mDrawFrame);
        }



        //this function contain the the main draw call
        /// this function need to call every time the code is executed
        // the thread call this functioin with some delay "drawspeed"
        public void drawFrame()
        {
            //getting the surface holder
            final SurfaceHolder holder = getSurfaceHolder();

            canvas = null;  // canvas
            try {
                canvas = holder.lockCanvas();  //get the canvas
                if (canvas != null) {
                    // draw something

                    // canvas matrix draw code
                    canvasDraw();
                    //^^^^
                }
            } finally {
                if (canvas != null)
                    holder.unlockCanvasAndPost(canvas);
            }

            // Reschedule the next redraw
            // this is the replacement for the invilidate funtion
            // every time call the drawFrame to draw the matrix
            mHandler.removeCallbacks(mDrawFrame);
            if (mVisible) {
                // set the execution delay
                mHandler.postDelayed(mDrawFrame, Drawspeed);
            }
        }






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

            // some matrix variable
            // though not needed
            Paint paint = new Paint();
            paint.setColor(background_color);
            paint.setAlpha(255); //set the alpha
            paint.setStyle(Paint.Style.FILL);
            canvas.drawRect(0, 0, width, height, paint);

        }
    }


    //old matrix effect code
    void drawText()
    {
        //Set up the paint
        Paint paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(text_color);
        paint.setTextSize(15);


        //loop and paint
        for(int i =0 ;i<textPosition.length;i++)
        {
            // draw the text at the random position
            canvas.drawText(""+textChar[rand.nextInt(textLength)+0],i*fontSize,textPosition[i]*fontSize,paint);
            // check if text has reached bottom or not
            if(textPosition[i]*fontSize > height && Math.random() > 0.975)
                textPosition[i] = 0;   // change text position to zero when 0 when text is at the bottom

            textPosition[i]++; //increment the position array
        }
    }

    //old martix effect code
    public void canvasDraw()
    {
        Log.d("canvas ","drawing");
        //set the paint for the canvas
        Paint paint = new Paint();
        paint.setColor(background_color);

        paint.setAlpha(5);
        paint.setStyle(Paint.Style.FILL);
        canvas.drawRect(0, 0, width, height, paint);//draw rect to clear the canvas

        drawText(); // draw the canvas

    }


}

这里使用以下方法来设置表面

public void onSurfaceCreated(SurfaceHolder holder)
 public void onVisibilityChanged(boolean visible)
 public void onSurfaceDestroyed(SurfaceHolder holder)
 public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height)

现在你有完整的工作动态壁纸代码。

获取源表单:https//github.com/sapandang/Matrix-Rain-Live-Wallpaper

Android创建自己的动态壁纸教程 转载https://www.codesocang.com/appboke/38815.html

技术博客阅读排行

最新文章