本例实现两个功能:

  1. 系统桌面上的app图标能够排列在我们的页面上。
  2. 点击自定义桌面上的app图标,能够打开对应的app。

实现思路:

  1. 我们知道,一个应用的启动页 Activity 的 Intent 的 filter 中 包含 actionIntent.ACTION_MAINcategoryIntent.CATEGORY_LAUNCHER 信息,我们构造一个这样的 Intent 来查询所有启动页 Activity 。
  2. 用一个 RecyclerView 来展示信息。
  3. 通过 Intent 跳转到对应 app 的主页面。

主要代码如下:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.sharpcj.launchertest.MainActivity"> <android.support.v7.widget.RecyclerView
android:padding="10dp"
android:id="@+id/rv_test"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" /> </android.support.constraint.ConstraintLayout>

recyclerview_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="100dp"
android:layout_height="100dp"> <ImageView
android:id="@+id/iv_icon"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_marginLeft="15dp"
android:layout_marginTop="10dp"/>
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="15dp"
android:layout_marginTop="5dp"
android:textSize="13sp"
android:maxLines="1"
android:ellipsize="end"
android:layout_gravity="center_horizontal"
/>
</LinearLayout>

MainActivity.java

package com.example.sharpcj.launchertest;

import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; public class MainActivity extends AppCompatActivity { private RecyclerView mRvTest;
private List<ResolveInfo> mlsResolveInfo;
private RvTestAdapter mAdapter; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRvTest = findViewById(R.id.rv_test);
mlsResolveInfo = new ArrayList<>(); mRvTest.setLayoutManager(new GridLayoutManager(this, 4));
mAdapter = new RvTestAdapter(MainActivity.this, mlsResolveInfo, new RvTestAdapter.OnItemClickListener() {
@Override
public void onClick(View view, int position) {
ResolveInfo resolveInfo = mlsResolveInfo.get(position);
startAppByResolveInfo(resolveInfo);
MainActivity.this.finish();
}
}); mRvTest.setAdapter(mAdapter); List<ResolveInfo> resolveInfos = queryMainActivitiesInfo();
mlsResolveInfo.addAll(resolveInfos);
mAdapter.notifyDataSetChanged(); } /**
* 查询所有包含启动 intent 的 Activity 信息(去掉本应用)
*
* @return
*/
private List<ResolveInfo> queryMainActivitiesInfo() {
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> resolveInfos = getPackageManager().queryIntentActivities(mainIntent, 0);
// 去掉本应用
Iterator<ResolveInfo> iterator = resolveInfos.iterator();
while (iterator.hasNext()) {
ResolveInfo resolveInfo = iterator.next();
String packageName = resolveInfo.activityInfo.packageName;
if (packageName.equals(getApplication().getPackageName())) {
iterator.remove();
}
}
return resolveInfos;
} private void startAppByResolveInfo(ResolveInfo resolveInfo) {
String pkg = resolveInfo.activityInfo.packageName;
String cls = resolveInfo.activityInfo.name;
ComponentName componet = new ComponentName(pkg, cls);
//打开该应用的主activity
Intent intent = new Intent();
intent.setComponent(componet);
startActivity(intent);
} }

RvTestAdapter.java

package com.example.sharpcj.launchertest;

import android.content.Context;
import android.content.pm.ResolveInfo;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView; import java.util.List; /**
* Created by SharpCJ on 2018/7/26.
*/ public class RvTestAdapter extends RecyclerView.Adapter<RvTestAdapter.ViewHolder> {
public interface OnItemClickListener {
void onClick(View view, int position);
} private Context mContext;
private List<ResolveInfo> mlsResolveInfo;
private OnItemClickListener mListener; public RvTestAdapter(Context context, List<ResolveInfo> resolveInfos, OnItemClickListener listener) {
this.mContext = context;
this.mlsResolveInfo = resolveInfos;
this.mListener = listener;
} public void setmListener(OnItemClickListener listener) {
this.mListener = listener;
} @Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.recyclerview_item, parent, false);
RvTestAdapter.ViewHolder viewHolder = new RvTestAdapter.ViewHolder(view, mListener);
return viewHolder;
} @Override
public void onBindViewHolder(ViewHolder holder, int position) {
ResolveInfo resolveInfo = mlsResolveInfo.get(position);
holder.imageView.setImageDrawable(resolveInfo.activityInfo.loadIcon(mContext.getPackageManager()));
holder.textView.setText(resolveInfo.activityInfo.applicationInfo.loadLabel(mContext.getPackageManager()));![](https://images2018.cnblogs.com/blog/758949/201807/758949-20180727193233793-2028954389.gif) } @Override
public int getItemCount() {
return mlsResolveInfo.size();
} class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
OnItemClickListener onItemClickListener;
ImageView imageView;
TextView textView; public ViewHolder(View itemView, OnItemClickListener onItemClickListener) {
super(itemView);
this.onItemClickListener = onItemClickListener;
imageView = itemView.findViewById(R.id.iv_icon);
textView = itemView.findViewById(R.id.tv_name);
itemView.setOnClickListener(this);
} @Override
public void onClick(View v) {
if (onItemClickListener != null) {
onItemClickListener.onClick(v, getAdapterPosition());
}
}
} }

运行效果如图:

一个简单的仿 Launcher 应用的更多相关文章

  1. 用Vue编写一个简单的仿Explorer文件管理器

    ​大家一定很熟悉你桌面左上角那个小电脑吧,学名Windows资源管理器,几乎所有的工作都从这里开始,文件云端化是一种趋势.怎样用浏览器实现一个Web版本的Windows资源管理器呢?今天来用Vue好好 ...

  2. 【Bugly干货分享】一起用 HTML5 Canvas 做一个简单又骚气的粒子引擎

    Bugly 技术干货系列内容主要涉及移动开发方向,是由Bugly邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟撰写而成,内容均属原创,转载请标明出处. 前言 好吧,说是“粒子引擎”还是大言不 ...

  3. 一起用HTML5 canvas做一个简单又骚气的粒子引擎

    前言 好吧,说是"粒子引擎"还是大言不惭而标题党了,离真正的粒子引擎还有点远.废话少说,先看demo 本文将教会你做一个简单的canvas粒子制造器(下称引擎). 世界观 这个简单 ...

  4. 自己实现的一个简单的EF框架(反射实现)

    我实现了一个简单的EF框架,主要用于操纵数据库.实现了对数据库的基本操纵--CRUD 这是项目结构 这是一个 core 下的 DLL 写了一个数据库工厂,用于执行sql语句.调用sql语句工厂 写了一 ...

  5. 使用 RxJS 实现一个简易的仿 Elm 架构应用

    使用 RxJS 实现一个简易的仿 Elm 架构应用 标签(空格分隔): 前端 什么是 Elm 架构 Elm 架构是一种使用 Elm 语言编写 Web 前端应用的简单架构,在代码模块化.代码重用以及测试 ...

  6. 5、使用Libgdx设计一个简单的游戏------雨滴

    (原文:http://www.libgdx.cn/topic/49/5-%E4%BD%BF%E7%94%A8libgdx%E8%AE%BE%E8%AE%A1%E4%B8%80%E4%B8%AA%E7% ...

  7. 实现一个简单的shell

    使用已学习的各种C函数实现一个简单的交互式Shell,要求:1.给出提示符,让用户输入一行命令,识别程序名和参数并调用适当的exec函数执行程序,待执行完成后再次给出提示符.2.该程序可识别和处理以下 ...

  8. Core1.1环境下,自己实现的一个简单的CRUD框架(反射实现)

    我实现了一个简单的EF框架,主要用于操纵数据库.实现了对数据库的基本操纵--CRUD 这是项目结构 这是一个 core 下的 DLL 写了一个数据库工厂,用于执行sql语句.调用sql语句工厂 写了一 ...

  9. Prism for WPF 搭建一个简单的模块化开发框架(五)添加聊天、消息模块

    原文:Prism for WPF 搭建一个简单的模块化开发框架(五)添加聊天.消息模块 中秋节假期没事继续搞了搞 做了各聊天的模块,需要继续优化 第一步画页面 页面参考https://github.c ...

随机推荐

  1. html几种美丽的分割线

    一.普通 1.<HR> 2.<HR align=center width=300 color=#987cb9 SIZE=1>align 线条位置(可选left.right.ce ...

  2. 描述JSP和Servlet的区别、共同点、各自应用的范围

    描述JSP和Servlet的区别.共同点.各自应用的范围 解答:JSP在本质上就是SERVLET,但是两者的创建方式不一样.Servlet完全是JAVA程序代码构成,擅长于流程控制和事务处理,通过Se ...

  3. Linux文件的打包与压缩

    打包命令: tar tar 的选项与参数非常的多!我们只讲几个常用的选项,更多选项您可以自行 man tar 查询罗! [root@www ~]# tar [-j|-z] [cv] [-f 创建的档名 ...

  4. Jmeter常用函数

    一._csvRead 函数 _cvsRead函数是从外部读取参数,csvRead函数可以从一个文件中读取多个参数. 步骤: 1.先新建一个文件,例如c.txt,里面的数据存放为 web@qq.com, ...

  5. PAT Advance 1014

    题目: 1014. Waiting in Line (30) 时间限制 400 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue S ...

  6. 2-SAT求任意解模板

    int stk[N],vis[N],low[N],link[N],mark[N]; int top,index,id,du[N];//记录入度数 int pre[N],cnt,g[N];// g 用来 ...

  7. 妈妈再也不用担心我使用git了

    妈妈再也不用担心我使用git了 Dec 29, 2014 git git由于其灵活,速度快,离线工作等特点而倍受青睐,下面一步步来总结下git的基本命令和常用操作. 安装msysgit 下载地址:ms ...

  8. UI层复习笔记

    在main文件中,UIApplicationMain函数一共做了三件事 根据第三个参数创建了一个应用程序对象 默认写nil,即创建的是UIApplication类型的对象,此对象看成是整个应用程序的一 ...

  9. shop++源码反编译----随笔

    一.applicationContext-mvc.xml配置 1.读取配置文件 <context:property-placeholder location="classpath*:/ ...

  10. SAFEARRAY的使用(转载)

    以下就是SAFEARRAY的Win32定义: typedef struct tagSAFEARRAY { unsigned short cDims; unsigned short fFeatures; ...