Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Launcher3--壁紙

Launcher3--壁紙

編輯:關於Android編程

在說Launcher上設置壁紙時,首先需要弄清楚的是,壁紙的設置屬於系統行為,而不是Launcher的應用特性。在Launcher中,壁紙的設置最終也是通過調用系統壁紙設置接口來完成的,所有,不僅僅是Launcher,很多第三方應用也是可以設置壁紙的。 Android中,可以使用WallpaperManager這一壁紙管理類來設置壁紙,有如下幾種方法, 我們可以根據壁紙資源的不同,選擇合適的方法,其中,最後一個可以用來設置動態壁紙。   下面就來說說Launcher3中是如何設置壁紙的,我們直接從壁紙設置界面的入口說起,
    /**
     * Event handler for the wallpaper picker button that appears after a long press
     * on the home screen.
     */
    protected void onClickWallpaperPicker(View v) {
        if (LOGD) Log.d(TAG, "onClickWallpaperPicker");
        final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);
        pickWallpaper.setComponent(getWallpaperPickerComponent());
        startActivityForResult(pickWallpaper, REQUEST_PICK_WALLPAPER);

        if (mLauncherCallbacks != null) {
            mLauncherCallbacks.onClickWallpaperPicker(v);
        }
    }
    protected ComponentName getWallpaperPickerComponent() {
        if (mLauncherCallbacks != null) {
            return mLauncherCallbacks.getWallpaperPickerComponent();
        }
        return new ComponentName(getPackageName(), LauncherWallpaperPickerActivity.class.getName());
    }
很顯然,LauncherWallpaperPickerActivity就是壁紙設置界面了,LauncherWallpaperPickerActivity繼承於WallpaperPickerActivity,WallpaperPickerActivity又繼承於WallpaperCropActivity,這麼多繼承,看來這個界面還是比較復雜的。從命名來看的話,也是為了區分每個類的處理重點,WallpaperCropActivity用來進行壁紙的裁剪,將圖片裁剪到合適的尺寸;WallpaperPickerActivity就是壁紙選擇器,選擇壁紙並設置;至於LauncherWallpaperPickerActivity,從代碼中看到只是重寫了父類的兩個方法,沒什麼可分析的,這裡我們重點分析WallpaperPickerActivity這個類。
一、壁紙類型對象 作為內部類,定義在WallpaperPickerActivity類中,
    public static abstract class WallpaperTileInfo {
        protected View mView;
        public Drawable mThumb;

        public void setView(View v) {
            mView = v;
        }
        public void onClick(WallpaperPickerActivity a) {}// 縮略圖點擊事件
        public void onSave(WallpaperPickerActivity a) {}// 設置壁紙,並做一些保存操作
        public void onDelete(WallpaperPickerActivity a) {}// 刪除壁紙
        public boolean isSelectable() { return false; }// 是否可選
        public boolean isNamelessWallpaper() { return false; }// 壁紙是否沒有名字
        public void onIndexUpdated(CharSequence label) {// 更新索引
            if (isNamelessWallpaper()) {
                mView.setContentDescription(label);
            }
        }
    }
壁紙對象的一個抽象類,不直接使用,具體的壁紙繼承該類並根據自身特點擴展。壁紙來源有多個途徑,如應用內置的壁紙、圖庫、第三方等,另外設為壁紙的方式也不一定相同,需要對不同來源區分處理,所有就定義了以下幾個壁紙類對象,
PickImageInfo--圖片選擇器,在Activity中添加屬性,就可以隱式調用到,如圖庫
UriWallpaperInfo--通過圖片的Uri來設置壁紙
FileWallpaperInfo--通過圖片文件來設置壁紙

ResourceWallpaperInfo--Launcher3中內置的壁紙資源來設置
DefaultWallpaperInfo--系統默認壁紙,資源在framework中
這幾個類實現其抽象父類中的方法,具體代碼實現就不一一細說,後面說到具體方法時會舉其中的例子來說明,這裡對幾個抽象方法已經做了注釋。   二、加載壁紙列表 圖1是壁紙設置界面,界面簡單,包含了壁紙列表、設置壁紙按鈕以及壁紙預覽圖等。 圖1 WallpaperPickerActivity中沒有重寫onCreate方法,而是通過父類的onCreate的方法調用了重寫的init方法,進行布局的加載和初始化。 1、布局




    

    

    

        

        

            

                

                

                
            
        

        
    

    WallpaperRootView是根視圖,繼承RelativeLayout自定義的一個視圖,重寫了fitSystemWindows方法,
    protected boolean fitSystemWindows(Rect insets) {
        a.setWallpaperStripYOffset(insets.bottom);
        return true;
    }
這麼做的目的是為了讓視圖內離底部一段距離,否則會出現如圖2的情況,跟虛擬鍵重合,就不大美觀了。

圖2
        setContentView(R.layout.wallpaper_picker);

        mCropView = (CropView) findViewById(R.id.cropView);
        mCropView.setVisibility(View.INVISIBLE);// 默認是不可見的

        mWallpaperStrip = findViewById(R.id.wallpaper_strip);
1)CropView--裁剪視圖,用於壁紙的裁剪、預覽,還有手勢操作(兩個手指縮放)。
2)進度條--加載該界面時的進度條。
3)壁紙列表--LinearLayout布局塊,其中的子視圖HorizontalScrollView是一個橫向的滑動視圖,就是我們的壁紙列表,也是根據壁紙類型的分了多個布局塊,分別加載。
    好像還少了ActionBar,這個是在代碼中動態添加的,下面會說到。

2、接口回調和監聽事件
        mCropView.setTouchCallback(new CropView.TouchCallback() {
            ViewPropertyAnimator mAnim;
            @Override
            public void onTouchDown() {
                if (mAnim != null) {
                    mAnim.cancel();
                }
                if (mWallpaperStrip.getAlpha() == 1f) {
                    mIgnoreNextTap = true;
                }
                mAnim = mWallpaperStrip.animate();
                mAnim.alpha(0f)
                    .setDuration(150)
                    .withEndAction(new Runnable() {
                        public void run() {
                            mWallpaperStrip.setVisibility(View.INVISIBLE);
                        }
                    });
                mAnim.setInterpolator(new AccelerateInterpolator(0.75f));
                mAnim.start();
            }
            @Override
            public void onTouchUp() {
                mIgnoreNextTap = false;
            }
            @Override
            public void onTap() {
                boolean ignoreTap = mIgnoreNextTap;
                mIgnoreNextTap = false;
                if (!ignoreTap) {
                    if (mAnim != null) {
                        mAnim.cancel();
                    }
                    mWallpaperStrip.setVisibility(View.VISIBLE);
                    mAnim = mWallpaperStrip.animate();
                    mAnim.alpha(1f)
                         .setDuration(150)
                         .setInterpolator(new DecelerateInterpolator(0.75f));
                    mAnim.start();
                }
            }
        });
    CropView的touch回調處理,這裡只做了一些動畫效果,具體裁剪的操作還是在CropView中實現的,這裡就不詳細說明了。
        mThumbnailOnClickListener = new OnClickListener() {
            public void onClick(View v) {
                if (mActionMode != null) {
                    // When CAB is up, clicking toggles the item instead
                    if (v.isLongClickable()) {
                        mLongClickListener.onLongClick(v);
                    }
                    return;
                }
                mSetWallpaperButton.setEnabled(true);
                WallpaperTileInfo info = (WallpaperTileInfo) v.getTag();
                if (info.isSelectable() && v.getVisibility() == View.VISIBLE) {
                    selectTile(v);
                }
                info.onClick(WallpaperPickerActivity.this);// 縮略圖點擊事件
            }
        };

縮略圖點擊事件,如果處於ActionMode(長按事件),處理長按事件,否則回調該壁紙所實現的onClick方法,啟用mSetWallpaperButton,該控件定義在其父類WallpaperCropActivity中,

// Action bar // Show the custom action bar view final ActionBar actionBar = getActionBar(); actionBar.setCustomView(R.layout.actionbar_set_wallpaper); actionBar.getCustomView().setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { boolean finishActivityWhenDone = true; cropImageAndSetWallpaper(imageUri, null, finishActivityWhenDone); } }); mSetWallpaperButton = findViewById(R.id.set_wallpaper_button);

        mLongClickListener = new View.OnLongClickListener() {
            // Called when the user long-clicks on someView
            public boolean onLongClick(View view) {
                CheckableFrameLayout c = (CheckableFrameLayout) view;
                c.toggle();
                if (mActionMode != null) {
                    mActionMode.invalidate();
                } else {
                    // Start the CAB using the ActionMode.Callback defined below
                    mActionMode = startActionMode(mActionModeCallback);
                    int childCount = mWallpapersView.getChildCount();
                    for (int i = 0; i < childCount; i++) {
                        mWallpapersView.getChildAt(i).setSelected(false);
                    }
                }
                return true;
            }
        };
    定義了縮略圖長按事件,並不是所有的壁紙類型都設置了長按事件,下面會講到。

3、獲取壁紙資源,將縮略圖加載到橫向scrollview

1)添加Launcher3中內置的壁紙資源和系統默認壁紙
        // Populate the built-in wallpapers
        // 填充內置壁紙,資源文件配置的壁紙和系統默認壁紙
        ArrayList wallpapers = findBundledWallpapers();
        mWallpapersView = (LinearLayout) findViewById(R.id.wallpaper_list);
        SimpleWallpapersAdapter ia = new SimpleWallpapersAdapter(this, wallpapers);
        populateWallpapersFromAdapter(mWallpapersView, ia, false);
通過findBundledWallpapers來查找壁紙,
    private ArrayList findBundledWallpapers() {
        final PackageManager pm = getPackageManager();
        final ArrayList bundled = new ArrayList(24);

        Partner partner = Partner.get(pm);
        if (partner != null) {
            final Resources partnerRes = partner.getResources();
            final int resId = partnerRes.getIdentifier(Partner.RES_WALLPAPERS, "array",
                    partner.getPackageName());
            if (resId != 0) {
                addWallpapers(bundled, partnerRes, partner.getPackageName(), resId);
            }

            // Add system wallpapers
            File systemDir = partner.getWallpaperDirectory();
            if (systemDir != null && systemDir.isDirectory()) {
                for (File file : systemDir.listFiles()) {
                    if (!file.isFile()) {
                        continue;
                    }
                    String name = file.getName();
                    int dotPos = name.lastIndexOf('.');
                    String extension = "";
                    if (dotPos >= -1) {
                        extension = name.substring(dotPos);
                        name = name.substring(0, dotPos);
                    }

                    if (name.endsWith("_small")) {
                        // it is a thumbnail
                        continue;
                    }

                    File thumbnail = new File(systemDir, name + "_small" + extension);
                    Bitmap thumb = BitmapFactory.decodeFile(thumbnail.getAbsolutePath());
                    if (thumb != null) {
                        bundled.add(new FileWallpaperInfo(file, new BitmapDrawable(thumb)));
                    }
                }
            }
        }

        // 添加Launcher中配置的壁紙
        Pair r = getWallpaperArrayResourceId();
        if (r != null) {
            try {
                Resources wallpaperRes = getPackageManager().getResourcesForApplication(r.first);
                addWallpapers(bundled, wallpaperRes, r.first.packageName, r.second);
            } catch (PackageManager.NameNotFoundException e) {
            }
        }

        // 創建一個空的實體,用於放置默認壁紙
        if (partner == null || !partner.hideDefaultWallpaper()) {
            // Add an entry for the default wallpaper (stored in system resources)
            WallpaperTileInfo defaultWallpaperInfo =
                    (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
                    ? getPreKKDefaultWallpaperInfo()
                    : getDefaultWallpaper();
            if (defaultWallpaperInfo != null) {
                bundled.add(0, defaultWallpaperInfo);
            }
        }
        return bundled;
    }
加載系統中有監聽特定廣播的應用中的資源,這個廣播是"com.android.launcher3.action.PARTNER_CUSTOMIZATION" 加載Launcher3中配置的壁紙,這些壁紙放在drawable-xxx目錄下,並在wallpapers.xml中配置(必須有原圖和縮略圖)

    
        
        zzz_wallpaper
        zzz_wallpaper_small
        
    
加載默認壁紙,默認壁紙放在framework資源目錄下
這樣就獲取到壁紙列表,定義適配器,通過populateWallpapersFromAdapter方法將其顯示,
    private void populateWallpapersFromAdapter(ViewGroup parent, BaseAdapter adapter,
                                               boolean addLongPressHandler) {
        for (int i = 0; i < adapter.getCount(); i++) {
            FrameLayout thumbnail = (FrameLayout) adapter.getView(i, null, parent);
            parent.addView(thumbnail, i);
            WallpaperTileInfo info = (WallpaperTileInfo) adapter.getItem(i);
            thumbnail.setTag(info);
            info.setView(thumbnail);
            if (addLongPressHandler) {// 是否添加長按事件,只對數據庫中保存的壁紙處理
                addLongPressHandler(thumbnail);
            }
            thumbnail.setOnClickListener(mThumbnailOnClickListener);
        }
    }
這個方法比較好理解,需要注意的是第三個參數,這個布爾值用來確定該類型壁紙是否添加長按事件,這裡是false,不添加;根據後面的分析來看,也只有保存在數據庫中的壁紙添加該操作,這也好理解,因為其他幾種類型都不是用戶自己定義的,不允許刪除壁紙,長按操作就是用來刪除該壁紙的。 2)添加保存在數據庫中的壁紙
        // Populate the saved wallpapers
        // 填充保存在數據庫中的壁紙
        mSavedImages = new SavedWallpaperImages(this);
        mSavedImages.loadThumbnailsAndImageIdList();
        populateWallpapersFromAdapter(mWallpapersView, mSavedImages, true);
3)添加動態壁紙
        // Populate the live wallpapers
        // 填充動態壁紙
        final LinearLayout liveWallpapersView =
                (LinearLayout) findViewById(R.id.live_wallpaper_list);
        final LiveWallpaperListAdapter a = new LiveWallpaperListAdapter(this);
        a.registerDataSetObserver(new DataSetObserver() {
            public void onChanged() {
                liveWallpapersView.removeAllViews();
                populateWallpapersFromAdapter(liveWallpapersView, a, false);
                initializeScrollForRtl();
                updateTileIndices();
            }
        });
在Android中,除了可以顯示靜態壁紙外,也可以使用動態壁紙。當然,跟普通的壁紙不同的是,它是已apk的形式安裝到手機中的(至於怎麼制作一個動態壁紙的apk,不是我們這邊所講的,就不闡述了),加載動態壁紙就是要查找系統中已安裝的動態壁紙應用。 動態壁紙也定義了一個適配器類LiveWallpaperListAdapter,定義動態壁紙對象,查找動態壁紙應用等。
    public LiveWallpaperListAdapter(Context context) {
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mPackageManager = context.getPackageManager();

        List list = mPackageManager.queryIntentServices(
                new Intent(WallpaperService.SERVICE_INTERFACE),
                PackageManager.GET_META_DATA);

        mWallpapers = new ArrayList();

        new LiveWallpaperEnumerator(context).execute(list);
    }
這是構造方法,查詢action為"android.service.wallpaper.WallpaperService"的service,這是動態壁紙應用中必須配置的,如果我們自己想做一個動態壁紙也是要添加這個action的。
    public static class LiveWallpaperTile extends WallpaperPickerActivity.WallpaperTileInfo {
        private Drawable mThumbnail;
        private WallpaperInfo mInfo;
        public LiveWallpaperTile(Drawable thumbnail, WallpaperInfo info, Intent intent) {
            mThumbnail = thumbnail;
            mInfo = info;
        }
        @Override
        public void onClick(WallpaperPickerActivity a) {
            Intent preview = new Intent(WallpaperManager.ACTION_CHANGE_LIVE_WALLPAPER);
            preview.putExtra(WallpaperManager.EXTRA_LIVE_WALLPAPER_COMPONENT,
                    mInfo.getComponent());
            a.onLiveWallpaperPickerLaunch(mInfo);
            a.startActivityForResultSafely(preview, WallpaperPickerActivity.PICK_LIVE_WALLPAPER);
        }
    }
WallpaperTileInfo的子類,然後異步加載信息。
            for (ResolveInfo resolveInfo : list) {
                WallpaperInfo info = null;
                try {
                    info = new WallpaperInfo(mContext, resolveInfo);
                } catch (XmlPullParserException e) {
                    Log.w(LOG_TAG, "Skipping wallpaper " + resolveInfo.serviceInfo, e);
                    continue;
                } catch (IOException e) {
                    Log.w(LOG_TAG, "Skipping wallpaper " + resolveInfo.serviceInfo, e);
                    continue;
                }

                // 獲取動態壁紙信息
                Drawable thumb = info.loadThumbnail(packageManager);
                Intent launchIntent = new Intent(WallpaperService.SERVICE_INTERFACE);
                launchIntent.setClassName(info.getPackageName(), info.getServiceName());
                LiveWallpaperTile wallpaper = new LiveWallpaperTile(thumb, info, launchIntent);
                publishProgress(wallpaper);
            }
4)第三方壁紙
        // Populate the third-party wallpaper pickers
        // 填充第三方壁紙選擇器
        final LinearLayout thirdPartyWallpapersView =
                (LinearLayout) findViewById(R.id.third_party_wallpaper_list);
        final ThirdPartyWallpaperPickerListAdapter ta =
                new ThirdPartyWallpaperPickerListAdapter(this);
        populateWallpapersFromAdapter(thirdPartyWallpapersView, ta, false);
加載第三方壁紙選擇器,這個還是很友好的,這樣手機中如果裝有其他的第三方壁紙設置的應用,也可以在此處顯示出來。查詢是在ThirdPartyWallpaperPickerListAdapter適配器類中進行的,這個適配器跟剛才說的動態壁紙適配器類類似。 定義了第三方壁紙對象ThirdPartyWallpaperTile,
    public static class ThirdPartyWallpaperTile extends WallpaperPickerActivity.WallpaperTileInfo {

        private ResolveInfo mResolveInfo;
        public ThirdPartyWallpaperTile(ResolveInfo resolveInfo) {
            mResolveInfo = resolveInfo;
        }

        @Override
        public void onClick(WallpaperPickerActivity a) {
            final ComponentName itemComponentName = new ComponentName(
                    mResolveInfo.activityInfo.packageName, mResolveInfo.activityInfo.name);
            Intent launchIntent = new Intent(Intent.ACTION_SET_WALLPAPER);
            launchIntent.setComponent(itemComponentName);
            a.startActivityForResultSafely(launchIntent, WallpaperPickerActivity.PICK_WALLPAPER_THIRD_PARTY_ACTIVITY);// 啟動第三方壁紙選擇器
        }
    }
在構造方法中查詢第三方壁紙應用,
    public ThirdPartyWallpaperPickerListAdapter(Context context) {
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mPackageManager = context.getPackageManager();
        mIconSize = context.getResources().getDimensionPixelSize(R.dimen.wallpaperItemIconSize);
        final PackageManager pm = mPackageManager;

        final Intent pickWallpaperIntent = new Intent(Intent.ACTION_SET_WALLPAPER);
        final List apps = pm.queryIntentActivities(pickWallpaperIntent, 0);

        // Get list of image picker intents
        Intent pickImageIntent = new Intent(Intent.ACTION_GET_CONTENT);
        pickImageIntent.setType("image/*");
        final List imagePickerActivities =
                pm.queryIntentActivities(pickImageIntent, 0);
        final ComponentName[] imageActivities = new ComponentName[imagePickerActivities.size()];
        for (int i = 0; i < imagePickerActivities.size(); i++) {
            ActivityInfo activityInfo = imagePickerActivities.get(i).activityInfo;
            imageActivities[i] = new ComponentName(activityInfo.packageName, activityInfo.name);
        }

        outerLoop:
        for (ResolveInfo info : apps) {
            final ComponentName itemComponentName =
                    new ComponentName(info.activityInfo.packageName, info.activityInfo.name);
            final String itemPackageName = itemComponentName.getPackageName();
            // Exclude anything from our own package, and the old Launcher,
            // and live wallpaper picker
            if (itemPackageName.equals(context.getPackageName()) ||
                    itemPackageName.equals("com.android.launcher") ||
                    itemPackageName.equals("com.android.wallpaper.livepicker")) {
                continue;
            }
            // Exclude any package that already responds to the image picker intent
            for (ResolveInfo imagePickerActivityInfo : imagePickerActivities) {
                if (itemPackageName.equals(
                        imagePickerActivityInfo.activityInfo.packageName)) {
                    continue outerLoop;
                }
            }
            mThirdPartyWallpaperPickers.add(new ThirdPartyWallpaperTile(info));
        }
    }
根據"android.intent.action.SET_WALLPAPER"來查找的,然後做一些過濾,添加到列表中。
5)添加圖庫
        // Add a tile for the Gallery
        // 列表開頭放置圖庫選擇器
        LinearLayout masterWallpaperList = (LinearLayout) findViewById(R.id.master_wallpaper_list);
        FrameLayout pickImageTile = (FrameLayout) getLayoutInflater().
                inflate(R.layout.wallpaper_picker_image_picker_item, masterWallpaperList, false);
        setWallpaperItemPaddingToZero(pickImageTile);
        masterWallpaperList.addView(pickImageTile, 0);

        // Make its background the last photo taken on external storage
        Bitmap lastPhoto = getThumbnailOfLastPhoto();
        if (lastPhoto != null) {
            ImageView galleryThumbnailBg =
                    (ImageView) pickImageTile.findViewById(R.id.wallpaper_image);
            galleryThumbnailBg.setImageBitmap(getThumbnailOfLastPhoto());
            int colorOverlay = getResources().getColor(R.color.wallpaper_picker_translucent_gray);
            galleryThumbnailBg.setColorFilter(colorOverlay, PorterDuff.Mode.SRC_ATOP);

        }

        PickImageInfo pickImageInfo = new PickImageInfo();
        pickImageTile.setTag(pickImageInfo);
        pickImageInfo.setView(pickImageTile);
        pickImageTile.setOnClickListener(mThumbnailOnClickListener);
在列表開頭添加圖庫入口,這樣用戶就可以選擇任一圖片了。 其他的初始化設置就不一一贅述了。   三、壁紙預覽和設置 之前說到不同類型的壁紙對象時,會重寫父類的方法,實現具體的功能,這裡我們已ResourceWallpaperInfo為例,來說明壁紙的預覽和設置的。
        @Override
        public void onClick(WallpaperPickerActivity a) {
            Log.d("dingfeng","ResourceWallpaperInfo onClick...");
            BitmapRegionTileSource.ResourceBitmapSource bitmapSource =
                    new BitmapRegionTileSource.ResourceBitmapSource(
                            mResources, mResId, BitmapRegionTileSource.MAX_PREVIEW_SIZE);
            bitmapSource.loadInBackground();
            BitmapRegionTileSource source = new BitmapRegionTileSource(a, bitmapSource);
            CropView v = a.getCropView();
            v.setTileSource(source, null);
            Point wallpaperSize = WallpaperCropActivity.getDefaultWallpaperSize(
                    a.getResources(), a.getWindowManager());
            RectF crop = WallpaperCropActivity.getMaxCropRect(
                    source.getImageWidth(), source.getImageHeight(),
                    wallpaperSize.x, wallpaperSize.y, false);
            v.setScale(wallpaperSize.x / crop.width());
            v.setTouchEnabled(false);
            a.setSystemWallpaperVisiblity(false);
        }
        @Override
        public void onSave(WallpaperPickerActivity a) {
            Log.d("dingfeng","ResourceWallpaperInfo onSave...");
            boolean finishActivityWhenDone = true;
            a.cropImageAndSetWallpaper(mResources, mResId, finishActivityWhenDone);
        }
        @Override
        public boolean isSelectable() {
            return true;
        }
        @Override
        public boolean isNamelessWallpaper() {
            return true;
        }
實現了四個方法,後面兩個返回bool值得含義之前已經說過,我們不細說。先看onClick,這個方法在點擊縮略圖列表是觸發,看看它究竟做了什麼。 這面用到了BitmapRegionTileSource及其內部類對象,這些類定義在src\main\java\com\android\photos\目錄下,自定義了圖片對象,實現了滾動、縮放等功能,這裡就不展開了,可以自己查看代碼 。 \
生成BitmapRegionTileSource對象後,設置到CropView上,然後做合適的縮放,再將系統壁紙設為不可見,這樣就可以達到壁紙預覽的目的。 再看onSave方法,這個方法在點擊ActionBar時調用,該方法中調用WallpaperCropActivity的cropImageAndSetWallpaper來裁剪和設置壁紙,
    protected void cropImageAndSetWallpaper(
            Resources res, int resId, final boolean finishActivityWhenDone) {
        // crop this image and scale it down to the default wallpaper size for
        // this device
        int rotation = getRotationFromExif(res, resId);
        Point inSize = mCropView.getSourceDimensions();
        Point outSize = getDefaultWallpaperSize(getResources(), getWindowManager());
        RectF crop = getMaxCropRect(inSize.x, inSize.y, outSize.x, outSize.y, false);
        Runnable onEndCrop = new Runnable() {
            public void run() {
                // Passing 0, 0 will cause launcher to revert to using the
                // default wallpaper size
                updateWallpaperDimensions(0, 0);
                if (finishActivityWhenDone) {
                    setResult(Activity.RESULT_OK);
                    finish();
                }
            }
        };
        BitmapCropTask cropTask = new BitmapCropTask(this, res, resId,
                crop, rotation, outSize.x, outSize.y, true, false, onEndCrop);
        cropTask.execute();
    }
設置裁剪大小,將其作為參數傳遞給異步任務執行,
        @Override
        protected Boolean doInBackground(Void... params) {
            return cropBitmap();
        }
最終就是cropBitmap方法來做最後的裁剪和壁紙設置操作。 其他幾種類型的壁紙也是類似的,根據壁紙來源做出相應的操作,比如第三方壁紙時,點擊縮略圖就是打開第三方應用;如果是圖庫,就打開圖庫,總之都是在這幾個重寫方法中實現的。如果以後有什麼不同於目前幾種類型的,也可以依此來擴展。
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved