Home例子研究

一. AndroidManifest.xml文件

1. 声明了几个权限<uses-permission android:name="xxx"/>

    <uses-permission android:name="android.permission.CALL_PHONE"/>
    <uses-permission android:name="android.permission.GET_TASKS"/>
    <uses-permission android:name="android.permission.READ_CONTACTS"/>
    <uses-permission android:name="android.permission.SET_WALLPAPER" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.EXPAND_STATUS_BAR"/>

2. 设置Activity的launchMode属性为singleInstance

参考:Activity的四种launchMode,Activity跳转时非常有用

3. 设置Activity的stateNotNeeded为true

这个属性默认情况为false,若设为true,则当Activity重新启动时不会调用onSaveInstanceState()方法,同样,onCreate()方法中的Bundle参数将会用null值传进去,也就是说,Activity每次启动都跟第一次启动一样。这样,在某种特殊场合下,由于用户按了Home键,该属性设置为true时,可以保证不用保存原先的状态引用,节省了空间资源,从而可以让Activity不会像默认设置那样Crash掉。
 
4. 添加category: android.intent.category.HOME
<category android:name="android.intent.category.HOME"/>
参考:ACTION,CATEGORY常量表
 
5. 添加action: android.intent.action.SET_WALLPAPER
<action android:name="android.intent.action.SET_WALLPAPER" />
 
二. layout-land/home.xml文件
 
1. All applications on the top side of the screen
 
    <GridView android:id="@+id/all_apps"
        android:background="@drawable/application_background"
        android:persistentDrawingCache="animation|scrolling"
        android:alwaysDrawnWithCache="true"
        android:scrollbars="none"
        android:drawSelectorOnTop="false"
        android:listSelector="@drawable/grid_selector"
        android:numColumns="auto_fit"
        android:columnWidth="78dp"
        android:stretchMode="spacingWidth"
        android:layout_weight="1.0"
        android:layout_height="0dip"
        android:layout_width="fill_parent"
        android:stackFromBottom="true"
        android:visibility="invisible" />
 
2. Favorites and Recents
 
    <com.example.android.home.ApplicationsStackLayout 
        android:id="@+id/faves_and_recents"
        home:stackOrientation="horizontal"
        home:marginLeft="1dip"
        home:marginRight="1dip"
        android:layout_marginTop="0dip"
        android:layout_width="fill_parent"
        android:layout_height="65dip"
        android:background="@drawable/application_background" />
 
三.
 
1. res/drawable/all_applications.xml
 
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_checked="false" android:drawable="@drawable/ic_launcher_allshow" />
    <item android:state_checked="true" android:drawable="@drawable/ic_launcher_allhide" />
</selector>
 
2. res/drawable/all_applications_button.xml
 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/show_all_apps"
    android:layout_width="78dip"
    android:layout_height="65dip"
    android:orientation="vertical"
    android:gravity="center_vertical"
    android:clickable="true"
    android:focusable="true"   
    android:background="@drawable/all_applications_button_background">

    <CheckBox
        android:id="@+id/show_all_apps_check"
        android:focusable="false"
        android:clickable="false"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/all_applications_background"
        android:button="@drawable/all_applications" 
        android:text="@string/show_all_apps" 
        android:textSize="12dip"
        android:maxLines="1"
        android:duplicateParentState="true"           
        android:textColor="@color/bright_text_dark_focused"
        android:gravity="center_horizontal" />

</LinearLayout>

3. 在ApplicationsStackLayout.initLayout方法中

// private View mButton;
// private LayoutInflater mInflater;

mInflater = LayoutInflater.from(getContext());
mButton = mInflater.inflate(R.layout.all_applications_button, this, false);
addView(mButton);

4. ApplicationsStackLayout继承自ViewGroup

class ApplicationsStackLayout extends ViewGroup implements View.OnClickListener

5. 在Home.bindApplications方法中

// private GridView mGrid;

mGrid = (GridView) findViewById(R.id.all_apps);

mGrid.setAdapter(new ApplicationsAdapter(this, mApplications));
mGrid.setSelection(0);

// private ApplicationsStackLayout mApplicationsStack;

mApplicationsStack = (ApplicationsStackLayout) findViewById(R.id.faves_and_recents);

6. 在layout/home.xml文件中

<com.example.android.home.ApplicationsStackLayout 
     android:id="@+id/faves_and_recents"

7. 在Home.bindRecents方法中

final ArrayList<ApplicationInfo> recents = new ArrayList<ApplicationInfo>();

mApplicationsStack.setRecents(recents);

8. 在Home.bindFavorites方法中

// private static LinkedList<ApplicationInfo> mFavorites;

mFavorites = new LinkedList<ApplicationInfo>();

mApplicationsStack.setFavorites(mFavorites);

9. 在Home.bindButtons方法中

// private View mShowApplications;

mShowApplications = findViewById(R.id.show_all_apps);
mShowApplications.setOnClickListener(new ShowApplications());

// private CheckBox mShowApplicationsCheck;
mShowApplicationsCheck = (CheckBox) findViewById(R.id.show_all_apps_check); 

mGrid.setOnItemClickListener(new ApplicationLauncher());

10. 在Home.onCreate方法中

bindApplications();
bindFavorites(true);
bindRecents();
bindButtons();

11. 在Home中定义ShowApplications

    private class ShowApplications implements View.OnClickListener {
        public void onClick(View v) {
            if (mGrid.getVisibility() != View.VISIBLE) {
                showApplications(true);
            } else {
                hideApplications();
            }
        }
    }

12. 在Home中定义ApplicationLauncher

    private class ApplicationLauncher implements AdapterView.OnItemClickListener {
        public void onItemClick(AdapterView parent, View v, int position, long id) {
            ApplicationInfo app = (ApplicationInfo) parent.getItemAtPosition(position);
            startActivity(app.intent);
        }
    }

13. 在layout/applications.xml中

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/label"
    android:layout_width="78dip"
    android:layout_height="65dip"
    android:paddingTop="4dip"
    android:textSize="12dip"
    android:singleLine="true"
    android:ellipsize="end"
    android:textColor="@color/bright_text_dark_focused"
    android:gravity="center_horizontal|center_vertical" />

14. 在Home.ApplicationAdapter.getView方法中

// 获取convertView

final LayoutInflater inflater = getLayoutInflater();
convertView = inflater.inflate(R.layout.application, parent, false);

// 获取icon

final ApplicationInfo info = mApplications.get(position);

Drawable icon = info.icon;

// 如果没有缩放 进行缩放处理

final Bitmap.Config c = icon.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
       : Bitmap.Config.RGB_565;
final Bitmap thumb = Bitmap.createBitmap(width, height, c);
final Canvas canvas = new Canvas(thumb)

canvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG, 0));

mOldBounds.set(icon.getBounds());
icon.setBounds(0, 0, width, height);
icon.draw(canvas);
icon.setBounds(mOldBounds);
icon = info.icon = new BitmapDrawable(thumb);

// 设置TextView的icon和text

final TextView textView = (TextView) convertView.findViewById(R.id.label);
textView.setCompoundDrawablesWithIntrinsicBounds(null, icon, null, null);
textView.setText(info.title);

15.  在Home.showApplications方法中

// Change the checked state of the view

mShowApplicationsCheck.toggle();

// private LayoutAnimationController mShowLayoutAnimation;

mShowLayoutAnimation = AnimationUtils.loadLayoutAnimation(this, R.anim.show_applications);

// 开始动画(Animation)

// private Animation mGridEntry;

mGridEntry.setAnimationListener(new ShowGrid());
mGrid.startAnimation(mGridEntry);

// 显示GridView

mGrid.setVisibility(View.VISIBLE);

16. 在Home.onCreate方法中

// private Animation mGridEntry;

mGridEntry = AnimationUtils.loadAnimation(this, R.anim.grid_entry);

17. ShowGrid实现接口Animation.AnimationListener

在ShowGrid.onAnimationEnd方法中

mBlockAnimation = false;

18. 在res/anim/grid_entry.xml文件中

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/decelerate_interpolator">
    <scale android:fromXScale="0.8" android:toXScale="1.0"
           android:fromYScale="0.9" android:toYScale="1.0"
           android:pivotX="100%" android:pivotY="100%" android:duration="200" />
    <alpha android:fromAlpha="0.5" android:toAlpha="1.0" android:duration="200" />
</set>

// fromXScale, toXScale, fromYScale, toYScale;

X、Y坐标上的伸缩尺寸 0.0表示收缩到没有, 1.0表示正常无伸缩, 值小于1.0表示收缩, 值大于1.0表示放大

// pivotX, pivotY; 

相对于物件的X、Y坐标的开始位置 从0%-100%中取值,50%为物件的X或Y方向坐标上的中点位置

// fromAlpha, toAlpha;

透明度 0.0表示完全透明 1.0表示完全不透明

// duration 动画持续时间,ms单位

19. 在res/anim/show_applications.xml文件中

<gridLayoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
        android:rowDelay="25%"
        android:directionPriority="column"
        android:direction="right_to_left|bottom_to_top"
        android:animation="@anim/fade_in" />

20. 在res/anim/fade_in.xml文件中

<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="50" />

参考:Android Animation学习笔记

  • alpha        渐变透明度动画效果
  • scale        渐变尺寸伸缩动画效果
  • translate  画面转换位置移动动画效果
  • rotate      画面转移旋转动画效果

21. 在res/anim/hide_applications.xml文件中

<gridLayoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
        android:rowDelay="25%"
        android:directionPriority="column"
        android:animation="@anim/fade_out" />

22. 在res/anim/fade_out.xml文件中

<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="50" />

23. 在res/anim/grid_exit.xml文件中

<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="200" />

24. 在Home.loadApplications方法中

// 获取PackageManager

PackageManager manager = getPackageManager();

// 创建Intent 其中action为main, category为launcher

Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);

// 获取mainIntent的activity列表 并且做排序

final List<ResolveInfo> apps = manager.queryIntentActivities(mainIntent, 0);
Collections.sort(apps, new ResolveInfo.DisplayNameComparator(manager));

// 创建application列表

final int count = apps.size();

mApplications = new ArrayList<ApplicationInfo>(count);

// 对于每个ApplicationInfo

ApplicationInfo application = new ApplicationInfo();
ResolveInfo info = apps.get(i);

application.title = info.loadLabel(manager);
application.setActivity(new ComponentName(info.activityInfo.applicationInfo.packageName,
        info.activityInfo.name), Intent.FLAG_ACTIVITY_NEW_TASK
       | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
application.icon = info.activityInfo.loadIcon(manager);

// 将application添加到列表
mApplications.add(application);

原文地址:https://www.cnblogs.com/fengzhblog/p/2751300.html