一个简单的仿 Launcher 应用
本例实现两个功能:
- 系统桌面上的app图标能够排列在我们的页面上。
- 点击自定义桌面上的app图标,能够打开对应的app。
实现思路:
- 我们知道,一个应用的启动页 Activity 的 Intent 的 filter 中 包含
action为Intent.ACTION_MAIN和category为Intent.CATEGORY_LAUNCHER信息,我们构造一个这样的 Intent 来查询所有启动页 Activity 。 - 用一个 RecyclerView 来展示信息。
- 通过 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()));
}
@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 应用的更多相关文章
- 用Vue编写一个简单的仿Explorer文件管理器
大家一定很熟悉你桌面左上角那个小电脑吧,学名Windows资源管理器,几乎所有的工作都从这里开始,文件云端化是一种趋势.怎样用浏览器实现一个Web版本的Windows资源管理器呢?今天来用Vue好好 ...
- 【Bugly干货分享】一起用 HTML5 Canvas 做一个简单又骚气的粒子引擎
Bugly 技术干货系列内容主要涉及移动开发方向,是由Bugly邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟撰写而成,内容均属原创,转载请标明出处. 前言 好吧,说是“粒子引擎”还是大言不 ...
- 一起用HTML5 canvas做一个简单又骚气的粒子引擎
前言 好吧,说是"粒子引擎"还是大言不惭而标题党了,离真正的粒子引擎还有点远.废话少说,先看demo 本文将教会你做一个简单的canvas粒子制造器(下称引擎). 世界观 这个简单 ...
- 自己实现的一个简单的EF框架(反射实现)
我实现了一个简单的EF框架,主要用于操纵数据库.实现了对数据库的基本操纵--CRUD 这是项目结构 这是一个 core 下的 DLL 写了一个数据库工厂,用于执行sql语句.调用sql语句工厂 写了一 ...
- 使用 RxJS 实现一个简易的仿 Elm 架构应用
使用 RxJS 实现一个简易的仿 Elm 架构应用 标签(空格分隔): 前端 什么是 Elm 架构 Elm 架构是一种使用 Elm 语言编写 Web 前端应用的简单架构,在代码模块化.代码重用以及测试 ...
- 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% ...
- 实现一个简单的shell
使用已学习的各种C函数实现一个简单的交互式Shell,要求:1.给出提示符,让用户输入一行命令,识别程序名和参数并调用适当的exec函数执行程序,待执行完成后再次给出提示符.2.该程序可识别和处理以下 ...
- Core1.1环境下,自己实现的一个简单的CRUD框架(反射实现)
我实现了一个简单的EF框架,主要用于操纵数据库.实现了对数据库的基本操纵--CRUD 这是项目结构 这是一个 core 下的 DLL 写了一个数据库工厂,用于执行sql语句.调用sql语句工厂 写了一 ...
- Prism for WPF 搭建一个简单的模块化开发框架(五)添加聊天、消息模块
原文:Prism for WPF 搭建一个简单的模块化开发框架(五)添加聊天.消息模块 中秋节假期没事继续搞了搞 做了各聊天的模块,需要继续优化 第一步画页面 页面参考https://github.c ...
随机推荐
- Tuning 12 manage statistics
这个 stattistics 对解析 sql 时的优化器有很重要的作用, 优化器是基于 statistics 来进行优化的. desc dbms_stats 包也可以 desc (早期使用 analy ...
- 让IE6支持min-width和max-width的方法
正如君所想象的一样,同实现层的fixed一样,用的是expression语句.例如div#demo在: IE6下最小宽度300px: 或 *html div#demo { width:expres ...
- Firefox模拟手机访问手机网站
说明: 此方法只能用以那些以识别UA来判断的网站 使用步骤: 第一步:打开Firefox,点击菜单,工具-〉附加组件-〉获取附加组件: 第二步:查询安装三个组件:User Agent Switcher ...
- java web学习笔记-Servlet篇
Servlet基础 1.Servlet概述 JSP的前身就是Servlet.Servlet就是在服务器端运行的一段小程序.一个Servlet就是一个Java类,并且可以通过“请求-响应”编程模型来访问 ...
- RedHat Ent 6.5 64bit编译安装hadoop2.4.1
RedHat Ent 6.5 64bit编译安装hadoop2.4.1 感谢原帖:http://blog.csdn.net/w13770269691/article/details/16883663/ ...
- ActiveMQ安装优化
ActiveMQ性能測试 http://m.blog.csdn.net/blog/brushli/41750615 1.下载ActiveMQ 官网:http://activemq.apache.org ...
- CodeFirst中DbContext动态添加DbSet
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.D ...
- mybatis 处理 mysql 表中的 text类型的 字段
在mysql 中 text类型的字段: service_detail text NULL 服务描述 . 对应java文件中 model 中的 String: private String ser ...
- 【BZOJ4621】Tc605 DP
[BZOJ4621]Tc605 Description 最初你有一个长度为 N 的数字序列 A.为了方便起见,序列 A 是一个排列. 你可以操作最多 K 次.每一次操作你可以先选定一个 A 的一个子串 ...
- 【BZOJ2259】[Oibh]新型计算机 最短路
[BZOJ2259][Oibh]新型计算机 Description Tim正在摆弄着他设计的“计算机”,他认为这台计算机原理很独特,因此利用它可以解决许多难题. 但是,有一个难题他却解决不了,是这台计 ...