要求说明书:
 1、设置一个默认的布局,命名为show_app_grid.xml
 整体是一个RelativeLayout设置背景色为#313849
 然后放置三个Layout组成
 1、 LinearLayout
 a) 高度为28px
 b) 布局方向为水平布局
 c) 子控件的对齐方式:垂直居中
 d) 左边预留5px的空间
 e) 设置背景图片为top_bg
 f) 包含两个控件
 i. ImageView
 1. 宽18px
 2. 高18px
 3. 图片:manage
 ii. TextView
 1. 高:wrap_content
 2. 高:wrap_content
 3. 颜色:#000
 4. 大小:14px
 5. 显示文字为:应用程序
 2、 GridView
 a) 配置id为:gv_apps
 b) 高、宽:fill_parent
 c) 列数:3
 d) Item之间的水平间隔和垂直间隔都是10px
 e) 当item选中时显示的图片为choose_gridview
 f) 距离父窗体的上下左右距离分别为28px、58px、5px、5px
 3、 RelativeLayout
 a) 宽:fill_parent
 b) 高:58px
 c) 紧靠父控件底部
 d) 背景图片:bottom_bg
 e) 有两个ImageButton
 i. 设置id分别为:ib_change_view和ib_change_category
 ii. 一个紧靠左边,一个紧靠右边
 iii. 距离父窗体:5px、1px
 iv. 图片分别为list和all
 v. 宽高为别为:76px和54px
 2、建立AppExplorerActivity.java
 去除Title、全屏显示
 requestWindowFeature(Window.FEATURE_NO_TITLE);
 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);显示所有软件信息
 1、 新建gv_item.xml为每一个item指定布局
 a) LinearLayout
 i. 高:wrap_content
 ii. 宽:90px
 iii. 布局方向:垂直
 iv. 设置里面的空间的位置为中间
 v. ImageView
 1. 设置id为gv_item_icon
 2. 宽高都为64px
 vi. TextView
 1. 设置id为gv_item_appname
 2. 宽高都为wrap_content
 3. 设置为2行
 4. 字体大小16px
 5. 颜色#FFF
 2、 建立GridViewAdapter
 3、 建立ViewHolder用来存放每一个item里的view
 4、 建立一个ArrayList用于放置获得所有的PackageInfo 小结:
  android:paddingLeft:指的是在本控件中,预留闲置多少空间
  android:layout_marginLeft:指的是这个控件距离父控件的空间有多少
 当GridView中的一项被点中的时候显示的背景图片:android:listSelector="@drawable/choose_gridview"
      android:numColumns="3" 指定GridView每一行的列数
      android:horizontalSpacing="10px" GridView中item间的水平间隔
      android:verticalSpacing="10px"   GridView中item间的垂直间隔 去除title: requestWindowFeature(Window.FEATURE_NO_TITLE);
  全屏显示:
 1、 获得这个Activity的Window对象
 a) Window win = getWindow()
 2、 为这个Window对象设置flag
 a) win.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
 WindowManager.LayoutParams.FLAG_FULLSCREEN);
  为一个GridView设置适配器的过程
 1、 为GridView的每一项准备一个布局文件
 2、 写一个类继承BaseAdapter
 i. 解释:一个类继承了BaseAdapter,需要重写几个方法,分别是getCount()、getItem()、getItemId()、getView()
 ii. 最重要的是getCount和getView方法。GridView中的每一项都是一个View。而这个View是通过getView获得的。当某一项需要显示的时候,它就会调用adapter中的getView方法获得需要展示的view。所以,这个GridView中有几项,就会调用几次getView方法,判断有几项,是通过getCount方法获得。所以在getCount中我们应该返回一个list的大小。在getView中,根据参数position获得list中位于position的某一个对象。通过LayoutInflater将布局文件渲染成一个view,再给这个view中的控件赋值
 3、 关于PackageInfo
 a) 获得系统中所有安装程序的信息,包括用户安装的和系统本身的:
 i. 获得PackageManager   pm = getPackageManager()
 ii. List list = pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES)
 b) PackageInfo封装了什么信息:可以理解为PackageInfo对应着一个Manifest文件,PackageInfo将Minifest的文件进行了封装
 i. 包名:packageName
 ii. 版本信息:versionCode、versionName
 iii. 这个包中的activity的信息
 iv. 这个包中receiver的信息
 v. 这个包中provider的信息
 vi. 这个包中service的信息  都封装成xxxInfo,通过这个就可以得到相应的信息
 vii. 还有可以获得applicationInfo
 1. 获得应用程序的名称applicationInfo.loadLabel(getPackageManager)
 2. 获得应用程序的图标(Drawable)
 applicationInfo.loadIcon(getPackageManager)加入加载过程的效果:
  当需要显示的项目很多,会造成很大的延迟。这时候屏幕会一直黑屏。给用户很不好的体验。应该在获取信息的时候,显示一些进度信息给用户看,增加用户体验
  介绍两种方式
 1、 使用ProgressDialog和Handler的使用
 a) 多线程:主线程显示ProgressDialog,新线程查询PackageInfo的信息。当新线程查询完毕之后,由handler发送一个消息给主线程,主线程得到消息,将ProgressDialog消失2、 使用Activity自带的效果,在title栏上显示进度信息
 a) requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);//先给Activity注册界面进度条功能
 b)  setProgressBarIndeterminateVisibility(true);//在需要显示进度条的时候调用这个方法
 c) setProgressBarIndeterminateVisibility(false);//在不需要显示进度条的时候调用这个方法响应切换用户程序和所有程序的按钮
  判断系统程序以及用户安装的程序
 if ((appInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
      // Updated system app
      flag = true;
 } else if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
      // Non-system app
      flag = true;
 }
 if (flag) {
  appList.add(appInfo);
 }
 通过查看源代码获得实现ListView的展现,过程和GridView很相似
  在布局文件中加入ListView控件,具体要求如下:
 配置id为:lv_apps
 高、宽:fill_parent
 Item之间的水平间隔和垂直间隔都是10px
 当item选中时显示的图片为choose_gridview
 距离父窗体的上下左右距离分别为28px、58px、5px、5px
 设置为不可见
 为ListView的每一项,写一个布局文件。lv_item.xml
 整体是一个LinearLayout,
 1、 布局方向为水平布局,
 2、 宽fill_parent
 3、 高wrap_content
 4、 内容的方向垂直居中
 5、 ImageView
 a) Id为lv_icon
 b) 距离父控件的顶部和底部都是5px
 c) 宽、高48px
 6、 LinearLayout
 a) 布局方向为垂直布局
 b) 宽wrap_content
 c) 高48px
 d) 左边预留5px的距离
 e) TextView
 i. Id为lv_item_appname
 ii. 宽fill_parent
 iii. 高wrap_content
 iv. 单行显示
 v. 字体大小16px
 vi. 字体样式:加粗
 vii. 字体颜色:#fff
 f) TextView
 i. Id为lv_item_packagenam
 ii. 宽fill_parent
 iii. 高wrap_content
 iv. 单行显示
 v. 字体颜色#fff
 属性android:ellipsize="marquee"
 Visibility属性:visibile
         gone
         invisibile
   三者之间的差别
 Toast是android用来提示消息的方式,它没有焦点,显示的时间有限,默认的Toast显示比较简单,就是一个TextView。自定义Toast
  每一个Toast中其实都有一个默认的view;我们可以new出一个view,在这个view中设置自己定义的样子,再设置到Toast里面就可以了响应item点击事件
  点击某一项的时候弹出一个Dialog,有启动程序、详细信息、卸载程序三个选项:
   在string.xml文件中定义<array>数组
       点击的position和list里面的对象位置是一致的
 启动程序:包名+类名
    包名:PackageInfo.packageName
          类名:ActivityInfo:PackageInfo.activities[0].name通过一个Intent:intent.setComponent(new ComponentName(packageName,activityName))
跳转到卸载程序页面:只能通过调用系统卸载界面,不能自己通过代码卸载。
 只需要一个URI就可以了
 Uri packageURI = Uri.parse("package:" + packageName);
   Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI);
   startActivity(uninstallIntent); 增加动画的效果
 1、 控制View的动画
 a) alpha(AlphaAnimation)
 渐变透明 
 b) scale(ScaleAnimation)
 渐变尺寸伸缩 
 c) translate(TranslateAnimation)
 画面转换、位置移动 
 d) rotate(RotateAnimation)
 画面转移,旋转动画 2、 控制一个Layout里面子View的动画效果
 a) layoutAnimation(LayoutAnimationController)
 b) gridAnimation(GridLayoutAnimationController)

Android13 app默认给所有权限_控件