一个简单的仿 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 ...
随机推荐
- JS动态增加删除UL节点LI及相关内容示例
<ul id="ul"> <li id=1>11111111111111111<a href="javascript:del(1);&quo ...
- phpcms利用广告位实现轮播图调用
如果我们使用自带的广告轮播,那么就是失去原有的轮播样式,这里就教大家一种使用广告轮播,还能保留原有的轮播样式 1.需要找到广告位的模块位置 3 下载广告代码 https://files.cnblogs ...
- .NET平台下 极光推送
正好看到别人发了个极光的推送例子,想来前面也刚做过这个,就把我的push类共享下 public class JPush { /// <summary> /// push信息到手机应用上 J ...
- Gradle学习系列之一——Gradle快速入门(转)
参考:https://www.cnblogs.com/davenkin/p/gradle-learning-1.html 记录,不做具体转载
- WHERE字句
structured query language(非过程性的结构查询语言) 主要内容: 数据库怎么限制里面的数据: 数据库怎么排列里面的数据. WHERE子句: --WHERE字句起到的是对数据库查 ...
- python uwsgi 部署以及优化
这篇文章其实两个月之前就应该面世了,但是最近琐事.烦心事太多就一直懒得动笔,拖到现在才写 一.uwsgi.wsgi.fastcgi区别和联系 参见之前的文章 http://www.cnblogs.co ...
- 面试题思考:Stack和Heap的区别
堆栈的概念: 堆栈是两种数据结构.堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除.在单片机应用中,堆栈是个特殊的存储区,主要功能是暂时存放数据和地址,通常 ...
- 59、常规控件(2)TextInputLayout-让EditText提示更加人性化
提示语用在显示. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" andro ...
- sql 存储过程,最简单的添加和修改
数据库表结构 <1>新增数据,并且按照"name" 字段查询,如果重复返回“error”=-100 ,如果成功返回ID,如果失败ID=0 USE [数据库]GOSET ...
- Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded.
EF6进行Insert操作的时候提示错误 Store update, insert, or delete statement affected an unexpected number of rows ...